• swoole process 消息通信


    swoole文档:Swoole 文档

    process子进程和父进程之间通信,依靠监听。子进程和父进程分别做监听。父进程写入信息,子进程监听接收。子进程向父进程写入,调用父进程监听。

    子进程向父进程写入信息有两种方式,一种调用write写入管道,一种是直接输出写入管道。在创建进程的时候控制。

    一 调用write写入管道

    1. function test3()
    2. {
    3. $p = new Swoole\Process(function ($worker) {
    4. Swoole\Event::add($worker->pipe, function () use ($worker) {
    5. $data = $worker->read();
    6. echo "sub:" . $data . PHP_EOL;
    7. $data = 'worker:' . $data;
    8. $worker->write($data); //写入父线程 2
    9. });
    10. }, false, 2);
    11. $p->start();
    12. Swoole\Event::add($p->pipe, function () use ($p) {
    13. $data = $p->read();
    14. echo 'P:' . $data . PHP_EOL; //最终输出 3
    15. });
    16. $p->write('123'); //请求子线程 1
    17. }
    18. test3();
    1. sub:123
    2. P:worker:123

    二 直接输出到管道

    1. function test2()
    2. {
    3. $p = new Swoole\Process(function ($worker) {
    4. Swoole\Event::add($worker->pipe, function () use ($worker) {
    5. $data = $worker->read();
    6. echo 'worker:' . $data . PHP_EOL; //直接写入父线程 2
    7. });
    8. }, true, 2);
    9. $p->start();
    10. Swoole\Event::add($p->pipe, function () use ($p) {
    11. $data = $p->read();
    12. echo 'P:' . $data . PHP_EOL; //最终输出 3
    13. });
    14. $p->write('123'); //请求子线程 1
    15. }
    16. test2();
    P:worker:123

    新建process之后,在其回调中创建的监听是子进程的监听,使用其对象创建的监听是父进程的监听。

    三 其他

    其实子进程不做监听也能收到父进程发送的信息,但是直接读信息和监听都存在的情况下,先执行直接读取的,可能监听不会执行。根据文档,监听必须在线程启动后设置。根据查的资料,event触发条件是句柄文件的改变,即类似于例子中的$p->pipe改变,否则不会触发。

    使用event监听是异步的。看到b站上有个例子代码如下

    1. public function onMessage(Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame)
    2. {
    3. $data = $frame->data;
    4. $data = json_decode($data);
    5. $cmd = $data['cmd']; //命令
    6. $fd = $frame->fd;
    7. $is_block = isset($data['is_block']) ? $data['is_block'] : 0;
    8. if ($is_block) {
    9. if (isset($this->process_list[$fd])) {
    10. $process = $this->process_list[$fd];
    11. } else {
    12. //新建子进程
    13. $process = new Swoole\Process([$this, 'do_time_process'], true, 2);
    14. $process->start();
    15. $this->process_list[$fd] = $process;
    16. Swoole\Event::add($process->pipe, function () use ($process, $frame) {
    17. $data = $process->read();
    18. $this->server->push($frame->fd, $data);
    19. });
    20. }
    21. $process->write($cmd);
    22. sleep(1);
    23. } else {
    24. $this->process->write($cmd);
    25. $data = $this->process->read();
    26. $this->server->push($frame->fd, $data);
    27. }
    28. }
    29. //子进程
    30. public function do_time_process(Swoole\Process $worker)
    31. {
    32. $cmd = $worker->read();
    33. //函数打开进程文件指针。打开一个指向进程的管道,该进程由派生指定的 command 命令执行而产生
    34. $handle = popen($cmd, 'r');
    35. Swoole\Event::add($worker->pipe, function () use ($worker, $handle) {
    36. $cmd = $worker->read();
    37. if ('exit' == $cmd) {
    38. $worker->exit();
    39. }
    40. //向管道写入内容
    41. fwrite($handle, $cmd);
    42. });
    43. //feof() 函数检查是否已到达文件末尾(EOF)
    44. while (!feof($handle)) {
    45. $str = fread($handle, 18192);
    46. $worker->write($str); //向父进程写入
    47. //echo $str;
    48. }
    49. }

    do_time_process中设置event监听的目的是,在执行不会自己结束的命令时,可以再次设置命令执行退出等操作。比如linux中ping命令。还没测试好,本来想写个例子试试,但是按照以上内容写的,子进程中的监听一直没有被触发。

    四 参考

    【swoole 入门课程】https://www.bilibili.com/video/BV1dt411a7Tb?p=4&vd_source=f1bd3b5218c30adf0a002c8c937e0a27

    swoole_event_add · Swoole文档 · 看云

    PHP swoole的process模块创建和使用子进程操作示例_php技巧_脚本之家

    带你学习swoole_process详解 · php开发笔记 · 看云

  • 相关阅读:
    设计模式-工厂方法(Factory Method)
    大学生影视主题网页制作 HTML+CSS+JS仿360影视网站 dreamweaver电影HTML网站制作
    Iterator 和 ListIterator 的区别(简要说明)
    <C++> 反向迭代器
    图像处理的基本操作
    C练题笔记之:Leetcode-793. 阶乘函数后 K 个零
    操作系统第一次实验——短作业优先调度算法(SJF)
    处理uniapp打包后有广告的问题
    gdb core dump使用简介
    Sulfo-Cyanine7 NHS ester活体成像用染料1603861-95-5星戈瑞
  • 原文地址:https://blog.csdn.net/lsswear/article/details/134263225