购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2 Linux进程间通信

每个进程都有各自独立的用户地址空间。每一个进程的数据对另一个进程是不可见的,所以进程之间不能进行相互访问。进程间要交换数据必须通过系统内核,也就是在内核中开辟一块缓冲区,通过缓冲区来进行进程间通信。例如,A进程把数据从用户空间复制到内核缓冲区,B进程再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(Inter Process Communication,IPC)。Linux进程间的通信机制可以分为6种:信号、管道、共享内存、FIFO(先进先出)队列、消息队列、Socket(套接字)。如图1-5所示。

图1-5 进程间通信方式

1.2.1 信号

信号(Singal)是UNIX系统最先开始使用的进程间通信机制,因为Linux继承自UNIX,所以Linux也支持信号机制。通过向一个或多个进程发送异步事件信号来实现通信,例如在终端上可以通过shell将任务发送给子进程。在命令控制台上输入kill-l可以查看系统支持的信号,如图1-6所示。

图1-6 系统支持的信号

一个进程收到其他进程发来的信号后可以选择处理,也可以选择忽略,但是SIGSTOP和SIGKILL这两个信号是不允许忽略的。SIGSTOP信号会通知当前正在运行的进程执行关闭操作,SIGKILL信号会通知杀死当前进程。除此之外的其他信号,进程可以按照业务场景自主选择。如果选择交给内核进行处理,那么就执行默认处理。操作系统会中断目标程序的进程来向其发送信号。在任何非原子指令中,执行都可以中断,如果进程已经注册了信号处理程序,那么就执行对应的程序,如果没有注册,将采用系统默认的处理方式。常见信号如表1-4所示。

表1-4 常见信号列表

1.2.2 管道

多个进程之间也可以通过建立管道(Pipe)来通信。在两个进程之间建立一个数据管道,一个进程向这个管道写入字节流,另一个进程从这个管道读取字节流。当进程尝试从空管道读取数据时,如果管道没有数据,则该进程会被阻塞,直到有可用数据为止。shell中的管线(pipeline)就是用管道实现的。在shell中按照指定内容读取文件就是通过管道完成的,例如cat xxx.txt|grep"1024"中的“|”就是管道连接符,两个应用程序不知道有管道的存在,一切都是由shell管理和控制。

1.2.3 共享内存

两个进程之间也可以通过共享同一块内存来进行进程间通信,其中两个或者多个进程可以访问公共内存空间,共享内存通信过程如图1-7所示。当两个进程通过共享内存(Shared Memory)进行通信的时候,其中一个进程修改共享内存的数据,另一个进程立即可以读取到修改的数据。

图1-7 共享内存通信

1.2.4 FIFO队列

FIFO队列通常也被称为命名管道(Named Pipe)。命名管道在工作方式上与普通管道是一样的。普通管道在进程退出或终止后,缓冲区将被回收,传输的数据会丢失。命名管道的数据保存在文件系统中,进程退出后数据不会丢失。进程间通信过程如图1-8所示。

图1-8 进程间通信过程

1.2.5 消息队列

消息队列(Message Queue)是一系列保存在内核中的消息链接列表。用户进程可以向消息队列添加消息,也可以从消息队列读取消息。与管道通信相比,消息队列的优势是为每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。消息队列有两种模式:一种是按照FIFO顺序接收与发送,另一种是支持无序的消息消费。

1.2.6 Socket

还有一种管理两个进程间通信的方法是使用Socket,Socket提供端到端的双向通信。一个Socket可以与一个或多个进程关联。Socket需要TCP或UDP等基础协议的支持。 UKUYPMAzd1aJrN3TnMvxjC0SQWBzj2WYzoCnY0KcA9QzpkGrpjFRJQLibzQANPEx

点击中间区域
呼出菜单
上一章
目录
下一章
×