1 Linux进程间通信方式
1.1 继承早期unix进程间通讯方式
1、无名管道(pipe);
2、有名管道(fifo);
3、信号灯(signal)。
1.2 System V IPC( Inter-Process Communication 进程间通信)
1、共享内存(share memory);
2、消息队列(message queue);
3、信号灯集(semaphore set)。
以上六种通讯方式用于本地进程间通讯。
1.2.1 System V IPC对象共同特点
1、IPC 对象包含:共享内容、消息队列和信号灯集;
2、每个IPC 对象有唯一的ID;
3、IPC对象创建后一直存在,直到进程结束或被显式的删除。所以,使用完IPC对象一定要记得删除。
4、Linux shell下常用IPC命令:
ipcs:查看IPC对象;
ipsrm:删除IPC对象。
5、每个IPC对象有一个关联的KEY(非负整数)。
KEY可以看做是IPC对象的属性,其作用是使不同的进程能打开同一个IPC对象。因为IPC对象的ID只能被创建其的进程获取,其他进程无法获取,所以想多个进程访问同一个IPC对象时只能利用KEY。
当KEY等于0时,表示其关联的IPC对象时私有的,只有创建它的进程可以打开它;当KEY为非零数时,多个进程可以方位此KEY关联的IPC对象。
生成IPC对象KEY值的函数
当多个进程想访问同一IPC对象时,这几个进程必须都调用ftok函数,且要使用相同测参数以保证KEY值一样。
1.3 套接字(socket)
套接字进程间通讯方式可用于本地,也可用于网络,但是一般是用于网络。
2 无名管道(pipe)
2.1 无名管道的特点
1、只能用于具有亲缘关系的进程之间的通讯。亲缘关系的进程:父子进程、兄弟进程、祖孙进程。
2、(一个无名管道)单工的通信模式,具有固定的读端和写端。要想实现双工,就得创建两个无名管道。
3、无名管道创建时会返回两个文件描述符,分别用于读管道和写管道。
2.2 无名管道的创建
注:EOF的值为-1。
注:管道内的数据是存在内存中的,只要被其它程序读一次,数据就消失了。
2.3 无名管道(有名管道)的读写特性
2.3.1 读特性
2.3.2 写特性
管道断裂指的是程序异常结束,也就是被信号结束。
3 有名管道(fifo)
3.1 定义
有名管道:管道被创建后有实际的文件与之对应,该文件有文件名、有路径,其文件类型属于管道文件(管道文件可读、可写,但是不能执行)。
有名管道对应文件后,对其操作变的就简单化了,就是对文件的操作。
3.1 有名管道特点
3.3 有名管道创建函数
3.4 有名管道读写特性
1、参见“2.3 无名管道(有名管道)的读写特性”;
2、当只有读端或只有写端是,打开有名管道(文件)时进程会阻塞等待。直到读端和写端同时存在,才能打开有名管道(文件)。
4 信号灯(signal)-中断
4.1 定义
信号:信号是在软件层次上对中断机制的一种模拟(正在执行的程序收到信号时会暂停,然后去响应信号,响应完信号后程序返回继续往下执行。),是一种异步通信方式(一个进程可随时就收信号,不需要做特殊处理)。
注:一个被执行的程序=进程。
4.2 进程对信号的响应方式
1、缺省方式,即默认处理方式;
2、忽略信号,即对信号不处理,相当于没有收到信号;
3、捕捉信号,也称注册信号,进程中对某一种或某一类信号设定信号处理函数,当进程收到该信号时就调用该信号的处理函数。
4.3 信号类型
Linux内核通过信号通知用户进程,信号分为不同的类型,代表不同的事件,如下图:
4.4 信号发送命令和函数
4.4.1 信号发送命令
4.4.2 信号发送函数
1、kill 可以向某一个进程或进程组发信号;
2、raise 只能向当前进程发信号;
3、参数pid取-1时,表示向除了init进程和本身进程以外的所有进程发信号;
4、参数sig习惯用宏,而不是数字。
4.5 创建定时器函数
1、Linux下一个程序中只能有一个定时器,当创建第n个定时器时,第n-1个定时器就失效了;
2、参数seconds为0时,表示取消当前计时器;
3、alarm函数常用于实现超时检测。
4.6 睡眠函数
函数pause使进程进入阻塞等待状态(睡眠),直到进程收到一个信号。进程先响应信号,然后从pause函数往下执行。
4.7 信号与函数关联函数
singal函数不是信号发送函数,它的作用是把信号和信号处理函数关联起来(也称为捕捉信号)。
5 System V IPC-共享内存
5.1 共享内存特点
1、共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据拷贝;
2、共享内存在内存中空间创建,可被进程映射到用户空间访问,使用灵活(进程不能直接访问内存空间);
3、由于多个进程可同时访问共享内存,因此需要同步和互斥机制配合使用。
5.2 共享内存使用步骤及相应函数
5.2.1 创建或打开共享内存
注:1、参数key值取IPC_PRIVATE宏(其值为0)时,表示这段共享内存是私有的,其只能被创建自己的进程访问,其他进程不能访问。流程如下去图。
2、参数size指共享内存的大小,单位为字节。
5.2.2 映射共享内存
即把指定的共享内存映射到进程地址空间用于访问
5.2.3 读写共享内存
1、由“5.2.2 映射共享内存”可知,共享内存映射函数返回值为指针,共享内存的访问形式(目标)就是指针。即我们通过指针访问共享内存。指针的类型取决于共享内存中存放的数据的类型。如下图所示的例子。
5.2.4 撤销共享内存映射
5.2.1 删除共享内存对象
注:1、shmctl 函数不仅能删除共享内存,而且能设置共享内存、获取共享内存属性,这都取决于其参数cmd的设置。
2、参数cmd取值:cmd取IPC_STAT时,shmctl函数的作用是获取共享内存属性;cmd取IPC_SET时,shmctl函数的作用是设置共享内存;cmd取IPC_RMID时,shmctl函数的作用是删除共享内存。
5.3 共享内存注意事项
1、因每块共享内存大小有限制,查询共享内存大小shell命令:ipcs -l;修改共享内存大小shell路劲:cat /proc/sys/kernel/shmmax。
2、共享内存删除时间点:调用共享内存删除函数shmctl(shmid,IPC_RMID,NULL)后并未真正删除共享内存,只是将其标记为删除。只有当共享内存相关的映射都取消,或相关进程都关闭时,才会真正删除共享内存。
6 System V IPC-消息队列
6.1 消息队列定义
消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等。
6.2 消息队列特点
1、消息队列是 System V IPC对象的一种;
2、消息队列由消息队列ID来唯一标识;
3、消息队列可以按照类型来发送/接受消息(最大特点)。
6.3消息队列结构
1、一个结构体(msqid_ds())描述消息队列属性;
2、一个链表存放消息队列数据。
6.4 消息队列使用步骤及相关函数
6.4.1 创建或打开消息队列-msgget函数
注:1、参数key值取IPC_PRIVATE宏(其值为0)时,表示这个消息队列是私有的,其只能被创建自己的进程访问,其他进程不能访问。
6.4.2 向消息队列发送消息-msgsnd函数
消息格式
6.4.1 从消息队列接受信息-msgrcv函数
注:参数msgtype如果取0,表示不是按消息类型接受,而是按消息产生的时间接受,即接受时间上最早的消息。
6.4.1 删除消息队列-msgctl函数
注:1、msgctl 函数不仅能删除消息队列,而且能设置消息队列、获取共享内存属性,这都取决于其参数cmd的设置。
2、参数cmd取值:cmd取IPC_STAT时,msgctl函数的作用是获取共享内存属性;cmd取IPC_SET时,msgctl函数的作用是设置共享内存;cmd取IPC_RMID时,msgctl函数的作用是删除共享内存;
3、调用msgctl函数删除消息队列时会立刻删除,不像删除共享内存时需要等待。
7 System V IPC-信号灯集
7.1 信号灯简介
信号灯也称信号量,用于进程/线程间通讯时的同步或互斥机制。
7.2 信号灯类型
1、Posix 无名信号灯,用于线程间通讯,是计数信号灯;
2、Posix 有名信号灯,是计数信号灯;
3、System V 信号灯集。
7.3 System V 信号灯集定义
System V 信号灯集是一个或多个计数信号灯的集合。
7.4 System V 信号灯集特点
可同时操作集合中的多个信号灯;申请多个资源时避免死锁。
7.5 System V 信号灯集使用步骤及相关函数
7.5.1 创建或打开信号灯集-semget
注:1、参数key值取IPC_PRIVATE宏(其值为0)时,表示这个信号灯集是私有的,其只能被创建自己的进程访问,其他进程不能访问。
7.5.2 信号灯集初始化-semctl
注:1、semctl 函数不仅能删除信号灯集,而且能初始化信号灯集,这都取决于其参数cmd的设置。
2、参数cmd取值:;cmd取SETVAL时,semctl 函数的作用是初始化信号灯集;cmd取IPC_RMID时,semctl 函数的作用是删除信号灯集;
7.5.3 P/V操作-semop
sembuf结构体描述对信号灯集具体P操作还是V操作。
7.5.4 删除信号灯集-semctl
注:1、semctl 函数不仅能删除信号灯集,而且能初始化信号灯集,这都取决于其参数cmd的设置。
2、参数cmd取值:;cmd取SETVAL时,semctl 函数的作用是初始化信号灯集;cmd取IPC_RMID时,semctl 函数的作用是删除信号灯集;
7.6 System V 信号灯集说明
1、 System V 信号灯集是一种同步或互斥机制,通常情况下信号灯集和共享内存一起配合使用;
2、关于信号灯的其他知识可参考“Linux之线程”文章中的“3.1 线程同步机制-信号量(灯)”段落。