Linux进程通信之共享内存

进程通信之共享内存

各个进程的虚拟内存是通过页表映射到物理内存中,而共享内存的实现就是允许两个不相关的进程映射到同一块物理内存,通过对该内存的读写数据以达到进程通信的目的。

共享内存是IPC进程通信方法中传输速度最快的方法,双方进程可以直接从内存中存取数据,而不需要双方进程之间进行拷贝。

共享内存的生命周期随内核,除非显示删除共享内存,就算是访问共享内存的进程都结束了,共享内存仍然在内核中存在,也就是说共享内存的生命周期与内核一致。

但是共享内存没有同步机制,在一个进程对共享内存进行写操作的时候,无法阻止另一个进程对其进行读操作。一般来说,会使用信号量来对共享内存同步访问控制。

共享内存的使用

c 复制代码
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, i int shmflg);
//key_t key是进程通信键值,ftok()的返回值,也可以手动指定并使用(key_t)进程强转。
//size_t 共享存储段的长度。
//int shmflg 标识函数的行为以及共享内存的权限。
  //IPC_CREAT\IPC_EXCL\位或者极限位
//成功返回共享内存的内存标识符;失败则返回-1。
c 复制代码
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
//将共享内存段映射到调用进程的数据段中
/*
shmid 共享内存的标识符,shmget的返回值
shmaddr 共享内存映射地址,通常使用NULL,表示由系统自动指定。
shmflg 共享内存段的访问权限和映射条件,
  0 可读可写
  SHM_RDONLY 只读
  SHM_RND shmaddr为空的时候才生效

成功返回共享内存段映射地址,失败返回-1
*/
c 复制代码
#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);
/*
将共享内存和当前进程分离。
shmaddr共享内存映射地址
成功执行返回0,失败返回-1
*/
c 复制代码
#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
/*
共享内存属性的控制
  shmid 共享标识符
  cmd 函数功能的控制
    IPC_RMID:删除
    IPC_SET:设置 shmid_ds 参数,相当于把共享内存原来的属性值替换为 buf 里的属性值。
    IPC_STAT:保存 shmid_ds 参数,把共享内存原来的属性值备份到 buf 里。
    SHM_LOCK:锁定共享内存段( 超级用户 )。
    SHM_UNLOCK:解锁共享内存段。  
    SHM_LOCK 用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。
  buf:shmid_ds 数据类型的地址,用来存放或修改共享内存的属性。
  成功返回0,失败返回-1
*/
c 复制代码
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int shmid; //共享内存标识符
    char *shmaddr;
    key_t key;
    key = ftok(".",1);     //获取键值
    shmid = shmget(key,1024*4,IPC_CREAT|0666); //打开或者创建共享内存
    if(shmid == -1){
        printf("shmget NO OK\n");
        exit(-1);
    }
    shmaddr = shmat(shmid,0,0);  //共享内存连接到当前进程的地址空间
    printf("shmat ok\n");
    strcpy(shmaddr,"hello world"); //向内存中写入数据
    sleep(5);                 //睡眠5秒,等待内存数据被读走
    shmdt(shmaddr);            //断开进程和内存的连接
    shmctl(shmid,IPC_RMID,0);  //删除共享内存段
    printf("quit\n");
    return 0;
}
c 复制代码
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int shmid;
    char *shmaddr;
    key_t key;
    key = ftok(".",1);        //获取键值
    shmid = shmget(key,1024*4,0); //打开创建的共享内存,获取内存ID,
    if(shmid == -1){
        printf("shmget no ok\n");
        exit(-1);
    }
    shmaddr = shmat(shmid,0,0); //共享内存连接到当前进程的地址空间
    printf("shmat ok\n");       //表示连接成功
    printf("data : %s",shmaddr); //将内存地址中的数据读出,打印
    shmdt(shmaddr);              //断开内存和当前进程的连接
    printf("quit\n");
    return 0;
}
相关推荐
聪明蛋子哟几秒前
浏览器自动化的“持久身份”:多会话认证与Agent技能的无缝集成实践
运维·自动化
千百元10 分钟前
ngrok 内网穿透TCP
运维
chen<>20 分钟前
C++ 六种 memory_order:从原子性到线程间可见性.md
java·linux·开发语言·c++
一直C22 分钟前
Linux系统编程|进程间通信IPC全套详解(1)(管道、信号)
linux·c语言·开发语言·网络·青少年编程·visual studio code
会周易的程序员30 分钟前
企业私有 AI 算力服务器架构设计:异构四节点 + QUIC 微服务
运维·服务器·c++·人工智能·微服务·架构
硬件工艺分享君37 分钟前
PCB厂家如何守住交期、品质与响应
大数据·运维·科技·制造·pcb工艺
库玛西40 分钟前
Linux网络编程:HTTP/HTTPS协议核心技术全解析
linux·运维·服务器·网络·c++·http·https
志栋智能1 小时前
大模型驱动运维:重构故障根因分析的“思考”逻辑
运维·服务器·重构·自动化
sxd20011 小时前
Vmware和multicast
linux·windows·vmware·无线桥接·multicast
暴力求解1 小时前
Linux网络---NAT代理服务、内网穿透
linux·网络·智能路由器