进程间通信(共享内存)
Posted 李憨憨_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信(共享内存)相关的知识,希望对你有一定的参考价值。
共享内存
一、共享内存
共享内存 : 用于进程间的数据共享
1.共享内存实现通信的原理
开辟一块物理内存空间, 各个进程将同一块物理内存空间映射到自己的虚拟地址空间中, 通过虚拟地址进行访问, 进而实现数据共享共享内存是最快的进程间通信方式, 因为通过虚拟地址空间映射后, 直接通过虚拟地址访问物理内存, 相较于其他方式少了两步数据拷贝的操作.
2.操作流程
1.创建或打开共享内存int shmget(key_t key, size_t size, int shmflg);
key: 标识符- -通过相同的标识符, 多个进程就可以打开同一块共享内存;
size: 要创建的共享内存大小;
shmflg: 打开方式 + 权限; IPC_CREAT: 不存在则创建, 存在则打开;
IPC_EXCL与IPC_CREAT搭配使用, 文件存在则报错, 不存在则创建打开;
返回值: 成功返回非负整数–操作句柄; 失败返回-1;
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid: shmget返回的操作句柄;
shmaddr: 映射的首地址, 通常置NULL;
shflg: SHM_RDONLY-只读; 0-可读可写;
返回值: 成功返回映射后的首地址; 失败返回(void*)-1;
凡是涉及到内存操作的接口, 都能对共享内存进行操作;memcpy, strcpy, printf...... 4.与进程间解除映射关系
int shmdt(const void *shmaddr);
shmaddr: shmat返回的映射首地址;
返回值: 成功返回0; 失败返回-1;
5.删除共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid: shmget返回的操作句柄;
cmd: 要对共享内存进行的操作类型;
IPC_CMD: 标记要删除的共享内存段;
映射连接数为0时删除共享内存; 禁止新的映射连接
返回值: 成功返回0; 失败返回-1;
二、代码实践
1.创建共享内存
代码如下(示例):
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <sys/shm.h>
5 #define IPC_KEY 0x01234567
6 #define PROJ_ID 0x01234567
7 int main()
8 {
9 //key_t key = ftok("./", PROJ_ID);
10 //shmget(标识符, 大小, 打开方式和权限)
11 int shmid = shmget(IPC_KEY, 32, IPC_CREAT | 0664);
12 if(shmid < 0){
13 perror("shmget error");
14 return -1;
15 }
16 return 0;
17 }
ipcs: 查看系统内核当中所有的进程间通信资源; ipcs -m: 查看共享内存; ipcs -q: 查看消息队列;ipcs -s: 查看信号量;
2.映射到虚拟地址
代码如下(示例):
16 //shmat(句柄, 映射首地址, 访问方式)
17 void *shm_start = shmat(shmid, NULL, 0);
18 if(shm_strat == (void*)-1){
19 perror("shmat error");
20 return -1;
21 }
22 while(1){
23 printf("%s\\n", (char*)shm_start);
24 sleep(1);
25 }
26 shmdt(shm_start);
27 //shmctl(句柄, 操作类型, 信息结构)
28 shmctl(shmid, IPC_RMID, NULL);
29 return 0;
30 }
3.修改共享内存(一个写, 一个读)
关闭read, write仍然一直在修改, 关闭write, read也一直在读, 两边互不影响
两边同时打开, 映射连接数为2;
总结
共享内存:通信原理: 开辟一块物理内存, 多个进程将同一块内存映射到自己的虚拟地址空间, 进行访问, 进而实现数据共享.
特性:
1.效率最高的进程间通信方式;
2.声明周期随内核;
注意事项: 各个进程对共享内存的操作都是不安全的操作
以上是关于进程间通信(共享内存)的主要内容,如果未能解决你的问题,请参考以下文章