linux创建子进程通信,Linux进程间通信的socketpair()函数

Linux的socketpair()函数,是创建一对互相连接着的socket描述符。

类似TCP连接,两个文件描述符都可以读写,sv[0]写入的数据在sv[1]读出,sv[1]写入的数据在sv[0]读出。

它的参数与socket()类似,只是多了一个int sv[2]项用于返回这两个文件描述符,返回值用于提示创建是否成功。

而socket()函数的返回值就是文件描述符,用返回-1提示失败。

ff5d6ce48a31c555e7d289069f263cb6.png

上图为它的man手册。

文件描述符,属于进程的资源之一,与进程的变量、代码类似,都会在fork()时被父子进程共享。

所以,socketpair()这个函数就被master+worker型的多进程服务器广泛用于master和各个worker的通信。

也可以用于子进程间的通信,因为第二个子进程被fork()时一样要共享父进程的socketpair,只要子进程间规定好谁使用1,谁使用2就行。

文件描述符在内核里对应着struct file结构,文件读写API最终都要处理内核的文件管理结构,文件描述符是这个结构的代号。

只要把某个文件的管理结构映射到某几个进程,他们就可以共享同一个文件了,在程序里的表现就是他们共享了同一对socketpair。

具体用法见如下三张图:

1,首先包含头文件“sys/types.h”和“sys/socket.h”,

2,然后在main()函数里先创建socketpair,然后再fork()子进程,这样子进程就共享了父进程的socketpair,

3,根据fork的返回值去判断出错、子进程、还是父进程,然后写不同的执行代码。

因为是进程间通信,所以使用AF_UNIX域(domain)的socket,类型选择SOCK_STREAM,类似TCP的可靠链接。

不要选SOCK_DGRAM,类似udp会在传输时丢包的。

3a3d1b66e8e2cb543212ffb19418b512.png

4bd5d50f0ced514d5ccee21a13c03b64.png

我们在父进程里fork了第二个子进程,让这两个子进程互相通信,一个使用sv[1]发送,一个使用sv[0]接收。

他们把各自不用的那个sv[i]关掉,只保留用的那个。

发送字符串时带着结尾的’\0’,6个字符,因为strlen不计算结尾的’\0’,所以发送长度要加1。

a42288c7a0d9e71c04be13b2ad5a777d.png

这里发送数据使用了socket的send()和recv()函数,阻塞式调用。

他们也可以配合epoll()机制进行非阻塞式的调用,是nginx服务器的底层基础。

运行结果图:

52778d3426b082902cbd5be2b66b36ab.png

PS:一个进程也可以在AF_UNIX域的socket上显式监听一个字符串表示的文件目录,等待其他进程去连接它,类似监听tcp的socket一样。

AF_UNIX的socketpair还可以把一个进程打开的文件,传递给另一个进程,这叫传递socket的附加数据,具体用法可以man一下cmsg。在Linux内核里就是把这个文件的管理结构struct file的指针加到目标进程的文件列表里。

举报/反馈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值