进程间通信之共享内存
来源:互联网 发布:chandler bing 知乎 编辑:程序博客网 时间:2024/06/16 05:12
进程间通信之共享内存
IPC对象
IPC对象这个概念需要理解,因为好多书或者料就直接说IPC就是共享内存、消息队列、信号灯集,其实IPC是一种机制,这种机制提供了进程间通信的通道,那么为什么加个System V呢,那是因为在System V 系统的四个版本中提出的进程通信的IPC这种机制。所以叫做System V IPC。
目前Linux也支持这三种机制:共享内存、消息队列、信号灯集
linux内核中定义了一个结构体:
struct ipc_perm{key_t key; 关键字uid_t uid; /*共享内存所有者的有效用户ID */gid_t gid; /* 共享内存所有者所属组的有效组ID*/ uid_t cuid; /* 共享内存创建 者的有效用户ID*/gid_t cgid; /* 共享内存创建者所属组的有效组ID*/unsigned short mode; /* Permissions + SHM_DEST和SHM_LOCKED标志*/unsignedshort seq; /* 序列号*/};
key比较关键,是识别这个共享通道的钥匙。
在这三种机制中都会用到这个创建的key;
一般用 ftok这个函数来创建钥匙。
key_t ftok( char * fname, int id )
例如:
if ((key = ftok(".", 's')) < 0) { perror("fail to ftok"); exit(-1); }
这样就产生了一个key,其实也可以自己定义key,但是这样定义的key不安全。所以尽量用ftok来产生key
共享内存
共享内存,它是一种最为高效的进程间通信方式,进程可以直接读写内存,不需要任何数据的拷贝
为了在多个进程间交换信息,内核专门留出了一块内存区,可以有需要访问的进程将其映射到自己的私有地址空间,这种机制要
建立在绝对信任的基础上,否则,如果系统的一些重要信息放在这块内存区的话,可能会被利用。
进程不需要拷贝,那么句大大提高了效率,由于多个进程共享一段内存,所以也需要依靠某种同步机制,如互斥和信号量等。
函数
函数所需头文件
#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>
共享内存的实现步骤:
##### 1. 创建/打开共享内存
int shmget(key_t key,int size,int shmflg);
函数参数:
- key:IPC_PRIVATE或ftok的返回值
- size:共享内存的大小
- shmflg:权限位
返回值:成功:共享内存段标识符
失败 -1;
2. 映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
void * shmat(int shmid,const void * shmaddr,int shmflg);
函数参数:
- shmid: 要映射的共享内存去标识符
- shmaddr:将共享内存映射到指定的地址(若为NULL,则表示由系统自动完成映射)
- shmflg:SHM_RDONLY 共享内存只读
默认为0:共享内存可读写
返回值: 成功,映射后的地址
失败 -1;
3. 撤销共享内存映射
int shmdt(const void * shmaddr);
函数参数:shmaddr:共享内存映射后的地址
函数返回值: 成功 0,失败 -1
4. 删除共享内存对象
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
函数参数:
- shmid:要操作的共享内存标识符
cmd: IPC_STAT(获取对象属性)
IPC_SET (设置对象属性)
IPC_RMID(删除对象)
buf:指定IPC_STAT/IPC_SET时用以保存/设置属性
返回值;成功 0,出错 -1;
程序源码
/******************************* write写端 *****************************/
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#define N 64typedef struct{ pid_t pid; char buf[N];} SHM;void handler(int signo){}int main(){ pid_t pid; key_t key; int shmid; SHM *shmadd;if ((key = ftok(".", 's')) < 0) { perror("ftok error:"); exit(-1); }signal(SIGUSR1, handler); if ((shmid = shmget(key, sizeof(SHM), 0666|IPC_CREAT|IPC_EXCL)) < 0) // not first process { if (errno == EEXIST) { shmid = shmget(key, sizeof(SHM), 0666); shmadd = (SHM *)shmat(shmid, NULL, 0); pid = shmadd->pid; shmadd->pid = getpid(); kill(pid, SIGUSR1); } else { perror("shmget error:"); exit(-1); } } else // first process { shmadd = (SHM *)shmat(shmid, NULL, 0); shmadd->pid = getpid(); pause(); pid = shmadd->pid; }while ( 1 ) { printf("write: "); fgets(shmadd->buf, N, stdin); kill(pid, SIGUSR1); if (strncmp(shmadd->buf, "quit\n", 5) == 0) break; pause(); } shmdt(shmadd); if (shmctl(shmid, IPC_RMID, NULL) < 0) { perror("shmctl error:"); }return 0;}
/******************************** read读端 *****************************/
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#define N 64typedef struct{ pid_t pid; char buf[N];} SHM;void handler(int signo){}int main(){ pid_t pid; key_t key; int shmid; SHM *shmadd;if ((key = ftok(".", 's')) < 0) { perror("ftok error:"); exit(-1); }signal(SIGUSR1, handler); if ((shmid = shmget(key, sizeof(SHM), 0666|IPC_CREAT|IPC_EXCL)) < 0) // not first process { if (errno == EEXIST) { shmid = shmget(key, sizeof(SHM), 0666); shmadd = (SHM *)shmat(shmid, NULL, 0); pid = shmadd->pid; shmadd->pid = getpid(); kill(pid, SIGUSR1); } else { perror("shmget error:"); exit(-1); } } else // first process { shmadd = (SHM *)shmat(shmid, NULL, 0); shmadd->pid = getpid(); pause(); pid = shmadd->pid; }while ( 1 ) { pause(); if (strncmp(shmadd->buf, "quit\n", 5) == 0) break; printf("read: "); printf("%s", shmadd->buf); kill(pid, SIGUSR1); } shmdt(shmadd);return 0;}
- linux进程间通信之共享内存
- 进程间通信之共享内存篇
- linux进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存篇
- 进程间通信之共享内存
- Linux进程间通信之共享内存
- Linux进程间通信之共享内存
- 进程间通信之共享内存
- Windows进程间通信之共享内存
- 进程间通信之共享内存
- 进程间通信之共享内存
- QT 进程间通信 之 共享内存
- 进程间通信IPC之--共享内存
- 进程间通信之共享内存
- linux进程间通信之共享内存
- 背包之01背包、完全背包、多重背包详解
- POJ 3356 (最长公共子序列)
- Ubuntu系统下R语言安装包的一些问题 (Rweibo)
- 源--Object
- NYOJ 02 括号配对问题
- 进程间通信之共享内存
- linux配置端口映射
- valgrind运行错误
- 前端基础学习之Html标签
- ngrok的使用
- iOS中真机运行报错bitcode解决方法
- 数据库多对多嵌套查询语句
- 运行AVD Manager提示要装Intel HAXM可是有提示not compatible with windows
- 机器学习(十四)