Linux系统编程系列(16篇管饱,吃货都投降了!)
1、Linux系统编程系列之进程基础
2、Linux系统编程系列之进程间通信(IPC)-信号
3、Linux系统编程系列之进程间通信(IPC)-管道
4、Linux系统编程系列之进程间通信-IPC对象
5、Linux系统编程系列之进程间通信-消息队列
6、Linux系统编程系列之进程间通信-共享内存
7、Linux系统编程系列之进程间通信-信号量组
8、Linux系统编程系列之守护进程
9、Linux系统编程系列之线程
10、Linux系统编程系列之线程属性
11、Linux系统编程系列之互斥锁和读写锁
12、Linux系统编程系列之线程的信号处理
13、Linux系统编程系列之POSIX信号量
14、Linux系统编程系列之条件变量
15、Linux系统编程系列之死锁
16、 Linux系统编程系列之线程池
一、什么是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()函数,然后需要指定不同的功能,更加详细的操作可以在本系列的其他三篇相关博客里寻找。