使用步骤

1. 创建子进程对象

  1. // 普通形式
  2. $process = new swoole_process('callback_function', true);
  3. // oop形式
  4. swoole_process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true);
  5. // 启用命名空间的方式
  6. Swoole\Process::__construct(callable $function, $redirect_stdin_stdout = false, $create_pipe = true)

这里需要注意的是,第二、第三个参数要填false或者0,表示不启用管道模式。

2. 启用消息队列

  1. swoole_process->useQueue(int $msgkey = 0, int $mode = 2);

useQueue方法接受2个可选参数。

$msgkey是消息队列的key,默认会使用ftok(FILE, 1)作为KEY

$mode通信模式,默认为2,表示争抢模式,所有创建的子进程都会从队列中取数据

如果创建消息队列失败,会返回false。可使用swoole_strerror(swoole_errno()) 得到错误码和错误信息。

使用模式2后,创建的子进程无法进行单独通信,比如发给特定子进程。

$process对象并未执行start,也可以执行push/pop向队列推送/提取数据

非阻塞模式

  1. $process->useQueue($key, $mode | swoole_process::IPC_NOWAIT);

在非阻塞模式下,队列已满调用push方法、队列已空调用pop方法时将不再阻塞立即返回。

3. 启动子进程

  1. function swoole_process->start()

4. 投递数据到消息队列

  1. Process->push(string $data);

5. 从消息对垒提取数据

  1. string Process->pop(int $maxsize = 8192);

6. 退出子进程

  1. Process->exit(int $status=0);

子进程退出后,在父进程中执行Process::wait可以得到子进程退出的事件和状态码。

完整例子

  1. <?php
  2. // 1.定义子进程对象数组
  3. $workers = [];
  4. // 2.最大进程数
  5. $workers_num = 2;
  6. // 3.批量创建子进程
  7. for($i = 0; $i < $workers_num; $i++){
  8. // 4.创建子进程
  9. $process = new swoole_process('doProcess', false, false);
  10. // 5.开启消息队列
  11. $process->useQueue();
  12. // 6.启动子进程
  13. $pid = $process->start();
  14. // 7.把子进程对象加到workers数组
  15. $workers[$pid] = $process;
  16. }
  17. // 子进程执行函数
  18. function doProcess(swoole_process $process){
  19. // 1.从消息队列获取数据
  20. $recv = $provess->pop();
  21. // 2.从主进程获取到的数据
  22. echo "从主进程获取到的数据是: $recv \n";
  23. sleep(5);
  24. // 3.退出子进程
  25. $process->exit();
  26. }
  27. // 主进程向 子进程添加数据
  28. foreach($workers as $pid=> $process){
  29. $process->push("hello,子进程$pid \n");
  30. }
  31. // 等待子进程结束,回收资源
  32. for($i = 0; $i < $workers_num; $i++){
  33. // 这里需要注意,当子进程exit之后,父进程一定要使用wait回收进程,否则将会成为僵尸进程
  34. // 1.等待子进程结束
  35. $ret = swoole_process::wait();
  36. // 2.从数组里移除子进程
  37. unset($workers[$pid]);
  38. echo "子进程$pid退出";
  39. }

这里需要特别注意:当子进程exit之后,父进程一定要使用wait回收进程,否则将会成为僵尸进程。