swoole 管道通讯 理解整理,代码演示

管道通讯:

Swoole进程间通信的方式

管道pipe

管道用于进程之间的数据交互,Linux系统本身提供了pipe函数用于创建一个半双工通信管道。半双工的通信方式中数据只能单向流动(一端只读一端只写),只能在具有亲缘关系(父子进程)的进程之间使用。

管道是进程间通信IPC中最基础的方式,管道有两种类型分别是命名管道、匿名管道。

匿名管道:专门用于具有血缘关系的进程之间,完成数据传递。

命名管道:可以用在任何两个进程之间,Swoole中的管道都是匿名管道。

在Swoole中利用eventfd和UnixSock封装了两种管道,使得进程之间的通信更加灵活。

Swoole的Process模块内置了管道的方式用于进程间通信,在构建Process实例时只要开启了$pipe_type选项,Swoole底层会自动创建一个管道,这里需要说明的时,虽然名字上叫做管道,但实际上在新版Swoole中底层通信是通过UnixSock实现的,所以并不是真正意义上的Linux Pipe。

管道类型$pipe_type可分为三种:

0表示不创建管道

1表示创建SOCK_STREAM类型的管道

2表示创建SOCK_DGRAM类型的管道

当启用$redirect_stdin_stdout后,$pipe_type选项将忽略用户参数,强制为1。

管道描述符

当进程被fork出来后,父进程和子进程中的Process对象会被设置上一个名为pipe的成员变量,存放着底层UnixSocket的描述符,父进程和子进程可以通过这个管道描述符来发送数据,也可以直接调用Process提供的read/write接口来收发数据。

管道读写

swoole_process->write(string $data) 向进程的管道中写入数据

swoole_process->read(int $buffer_size = 8192) 从进程的管道中读取数据

redirect_stdin_stdout  true 启用时 在管道中的数据 只能一次 第一次的数据写入到管道中。

例01:redirect_stdin_stdout = false;

例01:// 输入结果为

B1: 父写入 01

A1: 子写入 B2

B1: 父写入 01

A1: 子写入 B2

读写顺序一般 主write一次,子就要read一次。子write一次,然后主read一次,

master-->write()

work-->read()

work-->write()

master-->read()

这样才能有序的使用通道,才不会被阻塞。而且是一对一的,write 2 次,也要read 2次,先write先read。


示例02:

workerFunc 更改一下第二个参数 $redirect_stdin_stdout 说,设置为 true ,子进程会将 echo 写入到主管道。我把上面的代码改一下,看下输出结果是啥。


输出结果:

A1: B1: 父写入 01

A1: B1: 父写入 01

这里没有输出,"A1:子写入B2", 是因为 echo "B1: $recv\n"; 已经写入一和 echo "A1: ".$process->read() 形成了一次读写流程,要想输出"A1:子写入B2",就必须在 主进程中再读一次。看示例03。

示例03:

主进程再读取 B2写入


输出结果:

A1: B1: 父写入 01

A2: 子写入 B2

A1: B1: 父写入 01

A2: 子写入 B2

理解到主写子读、子写主读,这个思路后。就明白简单多了。$redirect_stdin_stdout 设置为 true时后 其中echo 也是一次 管道写入。

参考:https://www.bbsmax.com/A/WpdK7LAAdV/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容