Linux进程通信之共享内存
2016-08-23 13:30
519 查看
这里简介一下共享内存的编程的模型,其它细节以后有时间再补充
创建共享内存,得到一个ID(函数shmget)
把ID映射成虚拟地址/挂载 (函数shmat)
使用虚拟地址访问内核共享内存,可以使用任何内存函数函数与运算符号
卸载虚拟地址 (函数shmdt)
删除共享内存 ,函数shctl(修改,获取共享内存的属性)
这里看下几个函数
对于创建共享内存的进程来讲,这个函数返回共享内存的Id,而对于接收方进程来讲,它通过这个函数来获取共享内存的Id,而如何获取到相同的Id则是由第一个参数key来决定的,大概可以理解为,创建共享内存的时候,把传入的key和内存的Id关联起来,等到接收方传入相同的key的时候,便会返回相同的Id.而保证key相同的办法则可以通过ftok函数利用相同的目录来获取,这里不作详述。只需要知道,传入相同的key就可以获取共享内存的Id即可。
第二个参数size则是共享内存的大小
第三个参数需要注意一下,一般来讲,创建者进程,一般传入IPC_CREAT|IPC_EXCL|权限,而作为接收方,传入0即可,其他细节请查看手册。
调用成功则返回Id,否则返回-1
对接收方进程而言,最后一个参数传入0即可。
接着调用shmat来得到共享内存,进行读写。shmdt来进行卸载
最后是shmctl
第一个参数是由shmget返回的Id
第二个参数cmd 则是选择工作的方式
IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
IPC_RMID:删除这片共享内存
一般我们用来删除Id的话,传入IPC_RMID即可,接收方不需要删除共享内存
shmB.c
创建共享内存,得到一个ID(函数shmget)
把ID映射成虚拟地址/挂载 (函数shmat)
使用虚拟地址访问内核共享内存,可以使用任何内存函数函数与运算符号
卸载虚拟地址 (函数shmdt)
删除共享内存 ,函数shctl(修改,获取共享内存的属性)
这里看下几个函数
#include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);
对于创建共享内存的进程来讲,这个函数返回共享内存的Id,而对于接收方进程来讲,它通过这个函数来获取共享内存的Id,而如何获取到相同的Id则是由第一个参数key来决定的,大概可以理解为,创建共享内存的时候,把传入的key和内存的Id关联起来,等到接收方传入相同的key的时候,便会返回相同的Id.而保证key相同的办法则可以通过ftok函数利用相同的目录来获取,这里不作详述。只需要知道,传入相同的key就可以获取共享内存的Id即可。
第二个参数size则是共享内存的大小
第三个参数需要注意一下,一般来讲,创建者进程,一般传入IPC_CREAT|IPC_EXCL|权限,而作为接收方,传入0即可,其他细节请查看手册。
调用成功则返回Id,否则返回-1
对接收方进程而言,最后一个参数传入0即可。
接着调用shmat来得到共享内存,进行读写。shmdt来进行卸载
#include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr)
最后是shmctl
#include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);
第一个参数是由shmget返回的Id
第二个参数cmd 则是选择工作的方式
IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
IPC_RMID:删除这片共享内存
一般我们用来删除Id的话,传入IPC_RMID即可,接收方不需要删除共享内存
举个栗子
shmA.c#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/shm.h> #include <sys/ipc.h> #include <signal.h> key_t key; int shmId; int* p; int i=0; void handle(int s){ if(s==SIGINT){ shmdt(p); shmctl(shmId,IPC_RMID,0); exit(0); } } int main(){ signal(SIGINT,handle); //1. create shared memory // key=ftok(".",255); if(key==-1)printf("ftok error,%m\n"),exit(-1); shmId=shmget(key,4,IPC_CREAT|IPC_EXCL|0666); if(shmId==-1)printf("shmget error,%m\n"),exit(-1); //2. attach shared memory p=shmat(shmId,0,0); if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1); //3. use virtual address operate data while(1){ *p=i++;; sleep(1); } //4. deattach shared memory //5. control(delete shared memory) return 0; }
shmB.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/shm.h> #include <sys/ipc.h> #include <signal.h> key_t key; int shmId; int *p; void handle(int s){ if(s==SIGINT){ shmdt(p); exit(0); } } int main(){ signal(SIGINT,handle); //1. create shared memory key=ftok(".",255); if(key==-1)printf("ftok error,%m\n"),exit(-1); shmId=shmget(key,4,0); if(shmId==-1)printf("shmget error,%m\n"),exit(-1); //2. attach shared memory p=shmat(shmId,0,0); if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1); //3. use virtual address operate data while(1){ sleep(1); printf("num=%d\n",*p); } //4. deattach shared memory shmdt(p); //5. control(delete shared memory) // return 0; }
相关文章推荐
- Linux 进程通信--共享内存。
- Linux 进程通信--共享内存
- linux进程通信-共享内存
- linux 进程间的通信(五) 共享内存-2
- 进程通信之内存地址映射与共享,同时如何在Linux0.11下实现共享内存
- Linux进程通信--共享内存
- Linux进程通信 共享内存
- linux下进程间共享内存通信的问题
- Linux进程通信之POSIX共享内存
- linux进程间的通信(C): 共享内存
- Linux进程通信总结(三) --共享内存
- Linux下进程通信之共享内存
- linux 进程间的通信(五) 共享内存-1
- Linux 进程通信--共享内存
- Linux 进程通信--共享内存
- linux进程通信--共享内存
- linux基础编程:进程通信之System V IPC:消息队列,信号量,共享内存
- UNIX/LINUX编程学习之进程通信--共享内存
- linux进程间共享内存通信详解
- linux下通过共享内存在进程之间实现通信(system V)