一、什么是IPC对象
消息队列,共享内存和信号量组被称为IPC对象。各种不同的IPC其实是在不同时期逐步引入的,他们是在UNIX伯克利版本system-V中引入的三种通信方式。
二、IPC对象特性
1、在系统中使用键值(KEY)来唯一确定,类似文件系统中的文件路径。
2、当某个进程创建(或打开)一个IPC对象时,将会获得一个整形ID,类似文件描述符。
3、IPC对象属于系统,而不是进程,因此在没有明确删除操作的情况下,IPC对象不会因为进程的退出而消失。
三、IPC相关操作命令
1、查看IPC对象
(1)、查看所有IPC对象
ipcs -a # 查看所有IPC对象
(2)、查看所有消息队列
ipcs -q
(3)、查看所有共享内存
ipcs -m
(4)、查看所有信号量组
ipcs -s
2、创建IPC对象
在IPC通信对象中不管需要使用共享内存、信号量组、消息队列,都需要经历以下步骤:
(1)先获得通信对象的KEY值(相当于确定系统中某一个唯一的文件)
(2)把KEY值所对应的通信对象设置为指定的功能(共享内存,信号量组,消息队列)
获得通信对象的KEY值使用ftok()
#include <sys/types.h> #include <sys/ipc.h> // 函数原型 key_t ftok(const char *pathname, int proj_id); // 参数分析: pathname --> 随便写一个路径名但必须是真实存在的(建议使用当前路径) proj_id --> 随便写一个整型,用于区分在同一个项目汇总不同的对象 // 返回值: 成功 返回通信对象的KEY值 失败 返回-1
具体如何创建请移步到本系列另外的三篇相关博客有详细介绍,这里做简单演示。
(1)、创建消息队列
// IPC对象的案例 #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int main(int argc, char *argv[]) { // 1、获取KEY值 key_t msg_key = ftok("./", 666); if(msg_key == -1) { perror("ftok fail"); } // 2、指定功能为消息队列 int msg_id = msgget(msg_key, IPC_CREAT|0666); if(msg_id == -1) { perror("msgget fail"); } return 0; }
(2)、创建共享内存
// IPC对象的案例 #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int main(int argc, char *argv[]) { // 1、获取KEY值 key_t shm_key = ftok("./", 666); if(shm_key == -1) { perror("ftok fail"); } // 2、指定功能为共享内存 int shm_id = shmget(shm_key, 4096, IPC_CREAT|0666); if(shm_id == -1) { perror("shmget fail"); } return 0; }
(3)、创建信号量组
// IPC对象的案例 #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int main(int argc, char *argv[]) { // 1、获取KEY值 key_t sem_key = ftok("./", 666); if(sem_key == -1) { perror("ftok fail"); } // 2、指定功能为信号量组 int sem_id = semget(sem_key, 10, IPC_CREAT|0666); if(sem_id == -1) { perror("semget fail"); } return 0; }
3、删除IPC对象
(1)、删除消息队列
ipcrm -Q key # 使用KEY值来删除
ipcrm -q id # 使用消息队列的ID来删除
(2)、删除共享内存
ipcrm -M key # 使用KEY值来删除
ipcrm -m id # 使用共享内存ID来删除
(3)、删除信号量组
ipcrm -S key # 使用KEY值来删除
ipcrm -s id # 使用信号量组ID来删除
四、总结
这里对IPC对象进行简单介绍,IPC对象用唯一的key值来确定,但是不同类型的IPC对象的KEY值可以相同,上面已经验证。获取key值使用ftok()函数,然后需要指定不同的功能,更加详细的操作可以在本系列的其他三篇相关博客里寻找。