共享内存和信号量
共享内存
🌔🌔🌔🌔🌔
- 共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
- 共享内存在进程空间的映射:

使用共享内存通信的一般步骤
1、创建或者打开共享内存
2、进程A连接(映射)共享内存,写入数据
3、进程A断开
4、进程B连接(映射)共享内存,读取数据
5、进程B断开
6、释放共享内存
- 示意图:

创建共享内存
-
shmget函数:
#include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size,int shmflg);- 功能:创建或打开一块共享内存区。
- 参数:
- key:进程间通信键值,ftok() 的返回值。
- size:该共享存储段的长度(字节)。
- shmflg:标识函数的行为及共享内存的权限,其取值如下:
- IPC_CREAT:如果不存在就创建
- IPC_EXCL: 如果已经存在则返回失败
- 位或权限位:共享内存位或权限位后可以设置共享内存的访问权限
- 返回值: 成功返回共享内存标识符;失败返回-1。
共享内存的映射和解除映射
-
shmat函数:
#include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);-
功能: 将一个共享内存段映射到调用进程的数据段中
-
参数:
- shmid:共享内存标识符,shmget() 的返回值。
- shmaddr:共享内存映射地址(若为 NULL 则由系统自动指定),推荐使用 NULL。
- shmflg:共享内存段的访问权限和映射条件( 通常为 0 ),具体取值如下:
- 0:共享内存具有可读可写权限。
- SHM_RDONLY:只读。
- SHM_RND:(shmaddr 非空时才有效)
-
返回值: 成功返回共享内存段映射地址( 相当于这个指针就指向此共享内存 ) ;失败返回-1
-
-
shmdt函数:
#include <sys/types.h> #include <sys/shm.h> int shmdt(const void *shmaddr);-
功能: 将共享内存和当前进程分离
-
参数:
- shmaddr:共享内存映射地址。
-
返回值: 成功0 ;失败-1
-
共享内存操作函数
-
shmct函数:
#include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);- 功能: 共享内存属性的控制。
- 参数:
-
shmid:共享内存标识符。
-
cmd:函数功能的控制,其取值如下:
- IPC_RMID:删除
- IPC_SET:设置 shmid_ds 参数,相当于把共享内存原来的属性值替换为 buf 里的属性值。
- IPC_STAT:保存 shmid_ds 参数,把共享内存原来的属性值备份到 buf 里。
- SHM_LOCK:锁定共享内存段( 超级用户 )。
- SHM_UNLOCK:解锁共享内存段。
- SHM_LOCK 用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。
-
buf:shmid_ds 数据类型的地址,用来存放或修改共享内存的属性。
-
-
返回值: 成功0 ;失败-1
示例代码
-
本例程未使用信号量,写端停留5秒等待读端读取信息,配合信号量使用的代码见文末
-
写进程shm_w.c
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { int shmid; //共享内存标识符 char *shmaddr; key_t key; key = ftok(".",1); //获取键值 shmid = shmget(key,1024*4,IPC_CREAT|0666); //打开或者创建共享内存 if(shmid == -1){ printf("shmget NO OK\n"); exit(-1); } shmaddr = shmat(shmid,0,0); //共享内存连接到当前进程的地址空间 printf("shmat ok\n"); strcpy(shmaddr,"hello world"); //向内存中写入数据 sleep(5); //睡眠5秒,等待内存数据被读走 shmdt(shmaddr); //断开进程和内存的连接 shmctl(shmid,IPC_RMID,0); //删除共享内存段 printf("quit\n"); return 0; } -
读进程shm_r.c
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h>

最低0.47元/天 解锁文章
861

被折叠的 条评论
为什么被折叠?



