Linux进程间通信总结

1. pipe

(1)pipe是单工的,也就是是单方向的,读只能用fd[0],写只能用fd[1]。书上说是半双工的说法是不准确的,半双工指的是两个方向都可以通信,只不过不能同时罢了,但pipe只能单向通信。

(2)如果要使用pipe实现双向通信,则必须创建两个pipe,也就是两对fd,其中一个pipe由A到B,另一个pipe由B到A。即便是用在fork出的父子进程间也是如此,因为管道两端必须被A和B分别持有,也就是fork之后双方均必须关掉每个pipe的其中一端。

(3)如果写代码时不小心被多方持有了fd[1],则管道的内容只会被随机的由一方读到,即只会被读到一次。

(4)写端被关闭了,读端继续读的话,等管道中所有内容读完后,read会返回0表示写端已关闭,写端没关闭的话read阻塞。可以用fcntl设置非阻塞属性,则就可以用select/poll/epoll之类的进行处理了。

(5)读端已关闭,写端继续写的话,会触发SIGPIPE信号,SIGPIPE信号如果在代码中增加了信号处理函数,则调用信号处理函数后,write返回-1,如果没增加该信号的处理的话,进程会退出。

(6)pipe虽然被定位为进程间通信,但实际上在进程内部作为线程间通信手段也是十分常见的。

(7)由于pipe没有全局标识,它只能用在fork之间的进程中,特别注意,说fork间的进程并非指的是代码必须是一个程序,用在exec出的另外程序中也可以,给exec程序常用的方式是dup2(pipe1[0], STDIN_FILENO)和dup2(pipe2[1], STDOUT_FILENO),还有一种方式是可以把fd的值通过arg参数传递给exec的程序,exec的程序直接用该fd即可(当然这种方法只适用于exec程序进程尚未自有同样值的文件描述符时),无需再dup,因为文件描述符默认是没有开启O_CLOEXEC的,所以在fork时就已自动复制到新进程了。

(8) 借助于对pipe的read的阻塞的特性,pipe可以用于进程间同步,可参照<Linux-UNIX系统编程手册>44.3章节。

(9) pipe可以同时被多个写端执行写入,并且,只要一次写入的数据长度不超过PIPE_BUF(4096),系统可以保证写入是原子的,也就是内容不会混合。<Linux-UNIX系统编程手册>44.2章节。

2. socketpair

(1)socketpair是全双工的,通信双方各持一端,用这一端既能读也能写,即A用fd[0]读和写,B用fd[1]读和写。

(2)与pipe一样,内容只会被read到一次,如果被多方读取,则只会随机的被一方读到。

(3)与pipe一样,写端如果关闭了,读端继续读的话,等读完所有内容,read会返回0,写端没关闭的话read会阻塞。同样的,可以用fcntl设置非阻塞属性,以用select/poll/epoll之类的进行处理。

(4)与pipe一样,读端如果关闭了,写端继续写的话,会触发SIGPIPE信号,SIGPIPE信号如果在代码中增加了信号处理函数,则调用信号处理函数后,write返回-1,如果没增加该信号的处理的话,进程会退出。

(5)与pipe一样,虽然被定位为进程间通信,但实际上在进程内部作为线程间通信手段也是十分常见的。

(6)与pipe不一样的是,socketpair可以通过bind函数获取一个全局唯一标识,但这种方法会自动创建一个文件,并且程序需要自己保证删除这个文件,因此这种方式用起来比较复杂,除非确实需要用在无亲缘关系的进程间时才考虑用这种方式(APUE17.6便是用了这种方式在不相关的进程间建立了通信)。而实际上,与pipe一样,只要我们是用在fork之间的进程中,无论是否exec,是完全可以共享fd的,具体方法同上。

(7)在APUE17.4讲了如何在不相关的进程间传递文件描述符,注意,既然是在不相关进程间传递,那么文件描述符的值在两个进程间就不一定是相同了,所以它例子中sendmsg时并没有简单使用iov直接传递文件描述符的值,这也就是它特地使用msghdr的msg_control的原因,因为这是系统所规定的方法,将该cmsghdr结构的cmsg_level设置为SOL_SOCKET即表示想传递的是文件描述符。(https://www.cnblogs.com/my_life/articles/5189074.html)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值