⾯试⾼频题:进程之间的通信⽅式
⽂章⽬录
⾯试⾼频题:进程之间的通信⽅式
进程之间的通信⽅式,是⾯试的⾼频试题,我就被腾讯的⾯试官Cue到了,简单得列举出各种⽅式,⼤部分同学都能回答上,但是你知道通信⽅式之间的区别与效率,不太清楚的,可以收藏本⽂,先收藏,后读。
进程之间的通信⽅式
进程之间的通信⽅式,主要有⼀下⼏种
1. 管道,包括匿名管道、命名管道
2. 信号
3. 信号量
4. 消息队列
5. 共享内存
6. 本地套接字
管道
管道是⼀种半双⼯的通信⽅式,数据只能单向流动
匿名管道
匿名管道只能在具有亲缘关系的进程间使⽤,进程的亲缘关系通常指⽗⼦进程关系
// 需要的头⽂件
#include <unistd.h>
// 通过pipe()函数来创建匿名管道
// 返回值:成功返回0,失败返回-1
// fd参数返回两个⽂件描述符
/
/ fd[0]指向管道的读端,fd[1]指向管道的写端
// fd[1]的输出是fd[0]的输⼊。
int pipe (int fd[2]);
使⽤匿名管道进⾏进程间的通信的过程,可以⽤下⾯例⼦说明进程通信方式
⽗进程创建管道,得到两个⽂件描述符指向管道的两端
⽗进程fork出⼦进程,⼦进程也有两个⽂件描述符指向同⼀管道。
⽗进程关闭fd[0],⼦进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只⽀持单向通信)。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。
命名管道
不同于匿名管道之处在于它提供⼀个路径名与之关联,以FIFO的⽂件形式存在于⽂件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(
能够访问该路径的进程与FIFO的创建进程之间通信),因此,通过FIFO 不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。
信号
信号是⼀种⽐较复杂的通信⽅式,信号产⽣的条件:按键、硬件异常、进程调⽤kill函数将信号发送给另⼀个进程、⽤户调⽤kill命令将信号发送给其他进程,信号传递的消息⽐较少,主要⽤于通知接收进程某个事件已经发⽣。
信号量
信号量是⼀个计数器,可以⽤来控制多个进程对共享资源的访问。它常作为⼀种锁机制,防⽌某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同⼀进程内不同线程之间的同步⼿段。
消息队列
消息队列是消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信号传递信息少,管道只能承载⽆格式字节流以及缓冲区⼤⼩受限等特点。消息队列起信箱作⽤,到了就挂在那⾥,需要的
时候去取。消息队列提供了⼀种在两个不相关进程间传递数据的简单有效的⽅法。与命名管道相⽐:消息队列的优势在于,它独⽴于发送和接收进程⽽存在,这消除了在同步命名管道的打开和关闭时可能产⽣的⼀些困难。
共享内存
共享内存( shared memory ) :共享内存就是映射⼀段能被其他进程所访问的内存,这段共享内存由⼀个进程创建,但多个进程都可以访问。共享内存是最快的 IPC ⽅式(不需要从⽤户态到内核态的切换),它是针对其他进程间通信⽅式运⾏效率低⽽专门设计的。它往往与其他通信机制,如信号量,配合使⽤,来实现进程间的同步和通信。
本地套接字
进程间通信的⼀种⽅式是使⽤UNIX套接字sockaddr_un,⼈们在使⽤这种⽅式时往往⽤的不是⽹络套接字,⽽是⼀种称为本地套接字的⽅式。本地套接字⽤于本地进程间的通讯更安全和稳定。
使⽤套接字函数socket创建,不过传递的参数与⽹络套接字不同。域参数应该是PF_LOCAL或者PF_UNIX,⽽不能⽤PF_INET之类。本地套接字的通讯类型应该是SOCK_STREAM或SOCK_DGRAM,协议为默认协议。
创建了套接字后,还必须进⾏绑定才能使⽤。不同于⽹络套接字的绑定,本地套接字的绑定的是struct sockaddr_un结构。struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX,⽽sun_path是本地⽂件的路径。通常将⽂件放在/tmp⽬录下。
本地套接字的其他操作都与⽹络套接字相似。
参考⽂章
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论