3.1.2 进程间通信

来源:互联网 发布:南京软件科技大学2016 编辑:程序博客网 时间:2024/06/06 03:04

Unix传统上采用进程来作为编程模型。Linux采用fork系统调用创建传统进程,采用clone系统调用创建“轻量级进程”,即线程。线程间可以设置共享部分内容,所以创建效率较高,但由于共享了部分数据,所以可能会导致线程安全问题。

 

clone函数的flags字段记录共享标志。Linux定义了一组共享标志来决定线程间共享哪些字段。如将flags字段设置为CLONE_VM|CLONE_FILES,表示共享内存描述符、页表和打开文件表。

 

除了运行新程序的情况外,进程经常被用来作为编写网络程序的一种模式,来并行处理多个请求。进程一旦创立,父进程总是要监控其生命周期,采用wait/waitpid等方式防止僵尸进程,同时要进行进程间通信。postfix的master模块建立了status_fd管道,用来报告子进程状态。

 

进程和进程间通信共同构成了Unix的经典编程模式。管道在shell中被大量使用。

 

进程间通信方法有管道、FIFO、套接字、System VIPC(消息队列、信号量、共享内存)、RPC(远程过程调用)等。postfix大量采用了管道、FIFO、Unix域协议来进行进程间通信。RPC的经典应用即NFS(网络文件系统)。

 

管道是最古老的进程间通信方式,由pipe系统调用创建:

int pipe(intfiledes[2])

filedes数组存放两个文件描述符,[0]用来读,[1]用来写。管道只能在有共同祖先的进程间使用,一般用来进行父子进程通信。postfix的master模块创建了status_fd、master_sig_pipe和master_flow_pipe 3组管道,分别用来报告子进程状态、报告信号信息、协调收发信速度。新创建的子进程会关闭status_fd[0],即创建子进程到父进程的管道。

 

Linux索引节点数据结构分为VFS内存索引节点数据结构inode,和由具体文件系统实现的磁盘索引节点结构,如Ext2文件系统磁盘索引结构ext2_inode。pipe系统调用会创建一个inode结构和两个file结构。由于没有磁盘索引节点,所以无法在无共同祖先的进程间进行通信,FIFO管道可以解决该问题。

 

FIFO管道采用“先进先出”方式读写数据,最先写入的数据被最先读出。postfix的qmgr和pickup模块默认采用FIFO管道和其他进程通信。

 

Unix域协议采用与socketAPI相同的接口在同一台主机的进程间通信。在postfix的各个模块中,smtpd模块要提供网络服务,所以采用socket API。qmgr和pickup模块默认采用FIFO管道,其他模块均默认采用Unix域协议通信。

0 0
原创粉丝点击