共享内存
共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段)。
如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中。
如果一个进程更新了段中的数据,其他进程也立即会看到更新。
由一个进程创建的段,也可以由另一个进程读写。
每个进程都把它自己对共享内存的映像放入自己的地址空间。
创建共享内存区。
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shm-flg);
参数key既可以是IPC_PRIVATE,也可是是ftok函数返回的一个关键字。
参数size指定段的大小。
参数flags
–IPC_CREAT—创建共享内存段;
–IPC_EXCL—如果段已经存在,调用失败。
shmget成功返回段标示符,失败返回-1。
创建共享内存区。
int main(int arg, char * args[])
{
int shmid = shmget(IPC_PRIVATE, 1024, 0666);
if (shmid < 0)
printf("error\n");
else
printf("success\n");
return 0;
}
在命令行执行ipcs –m 显示,已经成功的创建了一块共享内存区。
nattch字段显示已经附加到这个内存区的进程数。
附加共享内存区。
void *shmat(int shmid, const void *shmaddr,int shmflg);
int shmdt(const void *shmaddr);
参数shmid是要附加的共享内存区标示符。
总是把参数shmaddr设为0。
参数shmflg可以为SHM_RDONLY,这意味着附加段是只读的。
shmat成功返回被附加了段的地址,失败返回-1,并设置errno。
函数shmdt是将附加在shmaddr的段从调用进程的地址空间分离出去,这个地址必须是shmat返回的。
shmat函数例子。
通过ipcs –m命令看到nattch字段显示有一个进程附加到共享内存。
int main(int arg, char * args[]) { char *shmbuf; int shmid = 0; if (arg > 1) { shmid = atoi(args[1]); shmbuf = shmat(shmid, 0, 0); sleep(60); shmdt(shmbuf); } return 0; }
共享内存读写例子。
int main(int arg, char * args[]) { char *shmbuf; int shmid = 0; if (arg > 2) { shmid = atoi(args[1]); shmbuf = shmat(shmid, 0, 0); if (atoi(args[2]) == 1) //write shared mem { scanf("%s\n", shmbuf); } if (atoi(args[2]) == 2) //read shared mem { printf("%s\n", shmbuf); } shmdt(shmbuf); } return 0; }