1. Principle and Implementation: nature under shared memory system V IPC mechanism was a special memory area, the need to share data between processes is placed in the shared memory region, all require access to the shared area of the process should be the shared area mapped into the address space of this process to go.
2.
1 #include <sys/types.h> 2 #include <sys/ipc.h> 3 #include <sys/shm.h>
1 key_t ftok(const char *pathname,int proj_id);
Used to create a keyword, a shared memory segment associated with the keyword.
Pathname parameter is a full path name of the file, and the file must be accessible.
Proj_id parameters are usually passed a non-zero character
You can create a unique key combination by pathname and proj_id
If the call succeeds, a return key, otherwise -1
1 #include<func.h> 2 int main(int argc,char *argv[]) 3 { 4 ARGC_CHECK(argc,2); 5 key_t key; 6 key=ftok(argv[1],1); 7 printf key 8 return 0; 9 }
以下四个函数都是系统调用
1 int shmget(key_t key,int size,int shmflg);
用于创建或打开一共享内存段,该内存段由函数的第一个参数唯一创建。函数成功,则返回一个唯一的共享内存标识号(相当于进程号,唯一的标识着共享内存),失败返回-1。
参数 shmflg 是一掩码合成值,可以是访问权限值与(IPC_CREAT 或 IPC_EXCL)的合成。IPC_CREAT 表示如果不存在该内存段,则创建它。IPC_EXCL 表示如果该内存段存在,则函数返回失败结果(-1)。如果调用成功,返回内存段标识,否则返回-1。
1 int shmid;//4k的整数倍 2 shmid=shmget(1000,4094,0600|IPC_CREAT); 3 ERROR_CHECK();
1 void *shmat(int shmid,const void *shmaddr,int shmflg);
将共享内存段映射到进程空间的某一地址。
参数 shmid 是共享内存段的标识 通常应该是 shmget 的成功返回值
参数 shmaddr 指定的是共享内存连接到当前进程中的地址位置。通常是 NULL,表示让系统来选择共享内存出现的地址。
参数 shmflg 是一组位标识,通常为 0 即可。
如果调用成功,返回映射后的进程空间的首地址,否则返回(char *)-1。
不能偏移
1 int shmid=shmget(1000,4094,0600|IPC_CREAT); 2 ERROR_CHECK(); 3 //先链接在fork,进程地址空间起始地址相同,先fork在链接,可能会不同 4 int *p=(int *)shmat(shmid,NULL,0);//创建共享内存时设定好了,所以填0 5 if(!fork())) 6 { 7 printf("i am child p[0]=%d\n",p[0]); 8 } 9 else 10 { 11 p[0]=100; 12 wait(NULL); 13 return 0; 14 } 15 //使用另外一个没有血缘关系的进程链接共享内存,也可以得到100
加1000万:
1 int main() 2 { 3 int shmid = shmget(1000, 4096, 0666 | IPC_CREAT); 4 ERROR_CHECK(shmid, -1, "shmget"); 5 int *p = (int *)shmat(shmid, NULL, 0); 6 int i; 7 * p = 0; 8 if (!fork()) 9 { 10 for (i = 0; i<10000000; i++) 11 { 12 * p += 1; 13 } 14 return 0; 15 } 16 else 17 { 18 for (i = 0; i<10000000; i++) 19 { 20 * p += 1; 21 } 22 wait(NULL); 23 printf("sum=%d\n", *p); 24 return 0; 25 } 26 }
结果小于等于2000万的随机数
并发 从内存写到寄存器,再从寄存器写到内存不是原子操作。
并发:两个或者两个以上继承操作同一个资源
并行:A进程写A文件,B进程写B进程
1 int shmdt(const void *shmaddr);
用于将共享内存段与进程空间分离。
参数 shmaddr 通常为 shmat 的成功返回值。
函数成功返回 0,失败时返回-1.注意,将共享内存分离并没删除它,只是使得该共享内存对当前进程不在可用。
1 int shmctl(int shmid,int cmd,struct shmid_ds *buf);
是共享内存的控制函数,可以用来删除共享内存段。
参数 shmid 是共享内存段标识 通常应该是 shmget 的成功返回值
参数 cmd 是对共享内存段的操作方式,可选为 IPC_STAT,IPC_SET,IPC_RMID。通常为 IPC_RMID,表示删除共享内存段。
有进程连接,执行返回 0,标记删除成功,但是最后一个进程解除连接后,共享内存真正被删除。
有人链接共享内存时,删除时无法删除,statue dest。标记删除。。最后一个进程解除链接时删除。标记删除只成功不失败。
1 int ret=shmctl(shmid,IPC_STAT,&buf);//这里存在结构体时,自己定义的,优先使用栈空间