16、 Linux系统编程系列之线程池
消息队列,共享内存和信号量组被称为IPC对象。各种不同的IPC其实是在不同时期逐步引入的,他们是在UNIX伯克利版本system-V中引入的三种通信方式。
1、在系统中使用键值(KEY)来唯一确定,类似文件系统中的文件路径。
2、当某个进程创建(或打开)一个IPC对象时,将会获得一个整形ID,类似文件描述符。
3、IPC对象属于系统,而不是进程,因此在没有明确删除操作的情况下,IPC对象不会因为进程的退出而消失。
(1)、查看所有IPC对象
ipcs -a # 查看所有IPC对象
(2)、查看所有消息队列
ipcs -q
(3)、查看所有共享内存
ipcs -m
(4)、查看所有信号量组
ipcs -s
在IPC通信对象中不管需要使用共享内存、信号量组、消息队列,都需要经历以下步骤:
(1)先获得通信对象的KEY值(相当于确定系统中某一个唯一的文件)
(2)把KEY值所对应的通信对象设置为指定的功能(共享内存,信号量组,消息队列)
获得通信对象的KEY值使用ftok()
- #include
- #include
-
- // 函数原型
- key_t ftok(const char *pathname, int proj_id);
-
- // 参数分析:
- pathname --> 随便写一个路径名但必须是真实存在的(建议使用当前路径)
- proj_id --> 随便写一个整型,用于区分在同一个项目汇总不同的对象
-
- // 返回值:
- 成功 返回通信对象的KEY值
- 失败 返回-1
具体如何创建请移步到本系列另外的三篇相关博客有详细介绍,这里做简单演示。
(1)、创建消息队列
- // IPC对象的案例
-
- #include
- #include
- #include
- #include
-
-
- 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
- #include
- #include
- #include
-
-
- 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
- #include
- #include
- #include
-
-
- 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;
- }
(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()函数,然后需要指定不同的功能,更加详细的操作可以在本系列的其他三篇相关博客里寻找。