首页 > 代码库 > Linux 进程通信(共享内存区)

Linux 进程通信(共享内存区)

共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段)。如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中。如果一个进程更新了段中的数据,其他进程也立即会看到更新。由一个进程创建的段,也可以由另一个进程读写。每个进程都把它自己对共享内存的映像放入自己的地址空间。
创建共享内存区int shmget(key_t key,size_t size,int shm-flg);参数key既可以是IPC_PRIVATE(IPC_PRIVATE表示让系统分配一个Key),也可以是ftok函数返回的一个关键字。参数size指定段的大小。参数flgs--八进制数,0666,转化为二进制后分别代表rw-rw-rw-shmget成功返回段标识符,失败返回-1(一般不会创建失败,除非系统没有内存).
//创建共享内存#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/ipc.h>#include <sys/shm.h>int main(int arg, char *args[]){    int shmid=shmget(IPC_PRIVATE,sizeof(char)*1024,0666);    if(shmid==-1)    {        printf("error\n");        return -1;    }    printf("创建共享内存成功!内存段标识符是%d\n",shmid);    return 0;}
在命令行执行"ipcs -m "显示已经成功的创建了一块共享内存区。nattch字段显示已经附加到这个内存区的进程数。

 

附加共享内存区void * shmat(int shmid,void * shmaddr,int shmflg);int shmdt(const * void shmaddr);参数shmid是要附加的共享内存区标识符(在命令行执行ipcs -m 显示)。总是把参数shmaddr设为0,0表示系统会自动在被附加的进程内创建一个内存段,映射到共享内存区。当然也可以指定一个被附加的进程内的一块内存,但是需要用户自己malloc分配内存,并将地址传给shmaddr参数,比较麻烦,一般使用系统自动分配。参数shmflg可以为SHM_RDONLY,这意味着附加段是只读的。shmat成功返回被附加了段的地址,失败返回-1,并设置errno。函数shmdt是将附加在shmaddr的段从调用进程的地址空间分离出去,这个地址必须是shmat返回的(即从自己进程内释放被附加的共享内存,强调不是释放系统的那个共享内存)。注意:进程里附加共享内存区的大小一定是和系统共享内存一样大,为了方便映射(两块内存不一样大如何同步数据?)。

 

Linux 进程通信(共享内存区)