CodeHelper CodeHelper
首页
JavaScript
PHP
Python
Git速查表 (opens new window)
博客 (opens new window)
首页
JavaScript
PHP
Python
Git速查表 (opens new window)
博客 (opens new window)
  • 开始

    • 使用
  • 函数方法

    • 请求
    • 多进程
      • pcntl_fork
目录

多进程

# pcntl_fork

  • 此函数只能在Linux下使用,而且需要安装pcntl的扩展
  • pcntl_fork()函数执行的时候,会创建一个子进程。子进程会复制当前进程,也就是父进程的所有数据,代码,还有状态;
  • 创建子进程成功后,在父进程内,返回子进程号,在子进程内返回0,失败则返回-1;

案例:

// 进程数
$forkNum = 3;
// 进程号记录
$pids = [];

$pageNum = 1;

echo '程序开始' . PHP_EOL;

for ($i = 0; $i < $forkNum; $i++) {
  $pid = pcntl_fork(); // 创建子进程;子进程代码完全复制(此时的)父进程,包括变量状态
  if ($pid) {
    echo '子进程创建成功:' . $i . ' - ' . $pid . PHP_EOL;

    $pageNum += 1;
    $pids[] = $pid;
    echo '子进程号:' . $pid . ' 已记录;' . PHP_EOL;
  } elseif ($pid == 0) {
    // sleep(2);
    echo '这里是第 ' . $i . ' 个子进程内部' . PHP_EOL;
    echo 'pageNum值为: ' . $pageNum . PHP_EOL;
    $pageNum = $pageNum * 2; // 并不会影响到别的进程此变量

    echo '第 ' . $i . ' 个子进程完成任务; exit;' . PHP_EOL . PHP_EOL;
    exit(); // 执行完,一定要结束,不然就会走进创建子进程的死循环
  } else {
    echo '创建子进程 ' . $i . ' 异常' . PHP_EOL;
  }
}

// 检查所有子进程状态
foreach ($pids as $pid) {
  // $res = pcntl_waitpid($pid, $status, WNOHANG); // WNOHANG 子进程没有退出的话 立马返回 0;使用这个的话就需要定时轮询反复检查状态

  // 等待指定pid的进程完成
  $res = pcntl_waitpid($pid, $status);
  if ($res == -1 || $res > 0) {
    if (!pcntl_wifexited($status)) {
      // 进程非正常退出
      echo "进程: $pid 非正常退出" . PHP_EOL;
    } else {
      // 获取进程终端的退出状态码;
      $code = pcntl_wexitstatus($status);
      echo "进程: $pid 已退出, 退出状态码为: $code" . PHP_EOL;
    }

    if (pcntl_wifsignaled($status)) {
      // 不是通过接受信号中断
      echo "进程: $pid 已退出, 但不是通过接受信号中断" . PHP_EOL;
    } else {
      $signal = pcntl_wtermsig($status);
      echo "进程: $pid 已退出, 是通过接受信号而中断的" . PHP_EOL;
    }
  }
}

输出

程序开始
子进程创建成功:0 - 288
子进程号:288 已记录;
这里是第 0 个子进程内部
pageNum值为: 1
第 0 个子进程完成任务; exit;

子进程创建成功:1 - 289
子进程号:289 已记录;
子进程创建成功:2 - 290
子进程号:290 已记录;
这里是第 1 个子进程内部
pageNum值为: 2
第 1 个子进程完成任务; exit;

这里是第 2 个子进程内部
pageNum值为: 3
第 2 个子进程完成任务; exit;

进程: 288 已退出, 退出状态码为: 0
进程: 288 已退出, 是通过接受信号而中断的
进程: 289 已退出, 退出状态码为: 0
进程: 289 已退出, 是通过接受信号而中断的
进程: 290 已退出, 退出状态码为: 0
进程: 290 已退出, 是通过接受信号而中断的
上次更新: 2022/11/11, 14:40:53
请求

← 请求

Theme by Vdoing | Copyright © 2022-2023 CodeHelper
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式