1、IPC(inter - process communication)通信
共享内存、消息队列、信号灯
2、库 <sys/shm.h>
2-1 创建共享内存
int shmget( key_t key, int size, int shmflg);
key : IPC_PRIVATE 或 ftok() 返回值
前者创建的共享内存 类似于 无名管道,只能实现 有亲缘关系 进程间的通信
例:int shmid; shmid = shmget( IPC_PRIVATE, 128, 0777);
后者创建的共享内存 类似于 有名管道,可实现 无亲缘关系 进程间的通信
size : 大小 shmflg : 权限
char ftok( const *path, char key);
例:int shmid; int key; key = ftok( "./a", 'b'); shmid = shmget( key, 128, IPC_CREAT | 0777);
2-2 通知 内核 将 共享内存 映射到 用户空间的地址中
映射到用户空间后,每次读写 共享内存 将无需 进入 内核
void *shmat( int shmid, const void *shmaddr, int shmflg);
shmflg : SHM_RDONLY 只读 默认为0 可读可写
例:char *p; p = (char *)shmat( shmid, NULL, 0);
2-3 删除用户空间中共享内存的地址映射
int shmdt( const void *shmaddr )
例:shmdt( p );
2-4 删除内核空间中共享内存
int shmctl( int shmid, int cmd, struct shmid_ds *buff);
cmd : IPC_STAT 获取对象属性 IPC_SET 设置对象属性IPC_RMID 删除对象
例:shmctl( shmid, IPC_RMID, NULL);
2-5 读写
写 fgets( p, 128, stdin); 写到哪里去、写多少个、写什么
读 printf( "%s", p);
2-6 特点
共享内存 创建之后,一直存在于 内核 中,直到 被删除 或 系统关闭
3、命令
查看IPC: ipc -m 共享内存 -q 消息队列 -s 信号灯
例:代码 system(" ipc -m") 命令 ipc -m
删除IPC:ipcrm -m <id>
例:代码 system(" ipcrm -m shmid") 命令 ipcrm -m <id>
代码:
1 #include <stdio.h>2 #include <sys/shm.h> //共享内存3 #include <string.h>//memcpy()4 5 int main()6 {7 int shmid;8 9 int key;10 11 char *p;12 13 //创建共享内存14 //shmid = shmget(IPC_PRIVATE, 128, 0777); //参数IPC_PRIVATE创建的共享内存 类似于 无名管道15 16 key = ftok("./a",'b'); //参数:文件路径及文件名、标识符17 if(key < 0)18 {19 printf("create key failure.\n");20 return -1;21 }22 printf("key = %X\n",key);23 24 //创建共享内存25 //shmid = shmget(key, 128, 0777); //报错26 shmid = shmget(key, 128, IPC_CREAT | 0777);//参数为ftok()的返回值 创建的共享内存 类似于 有名管道27 if(shmid < 0)28 {29 printf("share memory create failure\n");30 return -1;31 }32 printf("share memory 128M, shmid = %d\n.", shmid);33 system("ipcs -m");//查看共享内存34 //system("ipcrm -m shmid");//报错:参数解析失败35 36 //通知内核将共享内存 映射到 用户空间的地址中37 p = (char *)shmat(shmid, NULL, 0);38 if(p < 0)39 {40 printf("shmat operation failure.\n");41 return -1;42 }43 printf("***shmat success\n");44 //写入 45 fgets(p, 128, stdin); //写入共享内存:写到哪里去、写多少个、写什么46 //读取 47 printf("share memory data: %s\n", p);48 49 shmdt(p); //删除 共享内存在用户空间的地址映射50 //memcpy(p,"abcd",4); //删除映射后,再对该地址进行操作时,段错误!51 shmctl(shmid, IPC_RMID, NULL); //删除内核空间的 共享内存52 system("ipcs -m");53 return 0;54 }
执行:
代码:通过 shmctl( shmid, IPC_RMID, NULL ); 实现 命令“ ipcrm -m <id> ” 删除内核中 共享内存 的功能
1 #include <stdio.h>2 #include <sys/shm.h>3 4 int main(int argc, char *argv[])5 {6 int shmid;7 if(argc < 3)8 {9 printf("please enter more parameter.\n");10 return -1;11 }12 if(strcmp(argv[1],"-m") != 0)13 {14 return -1;15 }16 printf("delete share memory.\n");17 shmid = atoi(argv[2]); //atoi() 字符串 转为 整型18 shmctl(shmid, IPC_RMID, NULL); //等同于 ipcrm -m <shmid>19 system("ipcs -m");20 return 0;21 }