概述:
System V共享区在概念上类似于POSIX共享内存区。代之以调用shm_open后调用mmap的是,先调用shmget,再调用shmat。
相关函数:
shmdt函数:
int shmget(key_t key, size_t size, int shmflg); 返回:若成功返回为共享内存区对象,若出错返回-1。
key既可以是ftok的返回值,也可以是IPC_PRIVATE。
size以字节为单位指定内存的区的大小。当实际操作为创建一个新的共享内存区时,必须指定一个不为0的size的值。如果实际操作为访问一个已经存在的共享内存区,那么size为0。
oflag表示权限组合。
typedef struct stu { char name[32]; int age; }STU; int main(int argc,char *argv[]) { int shmid; shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666); if(shmid == -1) ERR_EXIT("shmget");
shmat函数:
void *shmat(int shmid, const void *shmaddr, int shmflg);返回:若成功则为映射区的起始地址,若出错则返回-1.
其中shmid是由shemget返回的标识符。shmat的返回值是所指定的共享内存区在调用进程内的起始地址。确定这个地址的规则如下:
如果shmaddr是一个空指针,那么系统替调用者选择地址。
如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND。
如果没有指定SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址;
如果指定了SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址向下舍入SHMLBA常值。
flag表示权限组合。
STU *p; p = shmat(shmid,NULL,0); if(p == (void*)-1) ERR_EXIT("shmat");
shmdt函数:
int shmdt(const void *shmaddr);返回:若成功返回0,若出错返回-1
当一个进程完成某个共享内存区的使用时,它可调用shmdt断接这个内存区。
shmdt(p);
shmctl函数:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl提供了对一个内存区的多种操作。该函数提供了三个命令:
IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它。
IPC_SET: 给所指定的共享内存区设置其shmid_ds结构的以下三个成员:shm_perm.uid、shm_perm.gid和shm_perm.mode 。
IPC_STAT:(通过buff参数)向调用者返回所指定共享内粗去当前的shmid_ds结构。
注:参考UNIX网络编程卷二:进程间同信
完整验证代码:
读:
#include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/shm.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/mman.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ }while(0); \ typedef struct stu { char name[32]; int age; }STU; int main(int argc,char *argv[]) { int shmid; shmid = shmget(1234, 0, 0); if(shmid == -1) ERR_EXIT("shmget"); STU *p; p = shmat(shmid,NULL,0); if(p == (void*)-1) ERR_EXIT("shmat"); printf("name = %s\nage=%d\n",p->name,p->age); memcpy(p,"quit",4); shmdt(p); return 0; }
写:
#include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/shm.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/mman.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ }while(0); \ typedef struct stu { char name[32]; int age; }STU; int main(int argc,char *argv[]) { int shmid; shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666); if(shmid == -1) ERR_EXIT("shmget"); STU *p; p = shmat(shmid,NULL,0); if(p == (void*)-1) ERR_EXIT("shmat"); strcpy(p->name,"lisi"); p->age = 20; while(1) { if(memcmp(p,"quit",4) == 0) break; } shmdt(p); shmctl(shmid, IPC_RMID, NULL); return 0; }