Linux共享内存实现进程间通信

来源:互联网 发布:二战美国驱逐舰数据 编辑:程序博客网 时间:2024/06/05 19:42

原理图:

通过在物理地址上开辟出一块内存,通过页表建立多个进程的虚拟内存与这块内存的映射,让进程可以访问这块空间,映射一旦建立就相当于进程自己拥有了这块内存。

特点:
通信速度快;
生命周期随内核;
不带任何同步机制,所以常常和信号量一块使用。

共享内存的操作:
创建:
int shmget(key_t key, size_t size, int shmflg);
参数描述:
key:由ftok()生成
size:内存的大小,一般设置为页的整数倍,如果小于页的整数倍则实际大小向上取整
shmflg:IPC_CREAT,表示存在获取,不存在创建;IPC_CREAT|IPC_ESCL,不存在创建,存在出错返回
返回值:
成功返回共享内存标识符,失败返回-1。
删除:
删除一般使用 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:标识一个共享内存
cmd:删除时为IPC_RMID
buf:删除时NULL
返回值:
成功返回0, 失败返回-1。
链接共享内存:
共享内存被创建之后,使用时要进行链接
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
shmid:标识一个共享内存
shmaddr:要连接的位置,一般为NULL,这样就交给了操作系统进行处理
shmflg:一般为0
返回值:
成功返回虚拟地址
取链接共享内存:
int shmdt(const void *shmaddr);
参数:
shmaddr:链接内存时返回的虚拟地址
返回值:
成功返回0,失败返回-1

实例代码:
实现父子进程去链接共享内存,子进程写内容,父进程取内容

comm.h
#ifndef _COMM_H_#define _COMM_H#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#define PATHNAME "."#define PJIO_ID 0x666int createShm();int getShm();int destroy();#endif

comm.c

#include"comm.h"static int commShm(int flags){    //生成一个key值,用来创建共享内存    key_t key = ftok(PATHNAME, PJIO_ID);    if(key < 0)    {    perror("ftok");    return -1;    }    //创建共享内存,按照flags形式创建    int shmid = shmget(key, 4096, flags);    if(shmid < 0)    {    perror("shmid");    return -2;    }    return shmid;}int createShm(){    //创建    return commShm(IPC_CREAT|IPC_EXCL|0666);}int getShm(){    //获取    return commShm(IPC_CREAT);}int destroy(int shmid){    //销毁    if(shmctl(shmid, IPC_RMID,NULL)<0)    {    return -1;    }    return 0;}

myshm.c

#include"comm.h"int main(){    //创建共享内存    int shmid = createShm();    //创建子进程    pid_t id = fork();    if(id == 0)//子进程    {    //子进程连接共享内存    char *shm = shmat(shmid, NULL, 0);    int i = 0;    while(i < 26)    {        //每隔一秒写入一个字符        shm[i] = 'A'+i;        i++;        sleep(1);    }    shm[i] = '\0';    //取消于共享内存的连接    shmdt(shm);    }    else//父进程    {    //连接共享内存    char *shm = shmat(shmid, NULL, 0);           int i = 0;    while(i<26)    {        //每隔一秒,将内存中的数据当作字符串进行访问        sleep(1);        printf("%s\n", shm);        i++;    }    //取消与共享内存的连接       shmdt(shm);    //回收子进程    wait(NULL);    //销毁共享内存    destroy(shmid);    }    return 0;}

运行结果:


原创粉丝点击