amphp/parallel
是一个可以在PHP中并行处理任务的库。你可以使用它来启动和管理子进程。
核心代码:
<?php
$phpCode = <<<'PHP'
<?php
// 子进程:初始化状态
$status = "wait";// 子进程:创建一个循环,等待指令
while (true) {// 从 stdin 读取指令$command = trim(fgets(STDIN));if ($command === "stop") {$status = "stopped";echo "Process stopped\n";break;} elseif ($command === "status") {echo "Current status: $status\n";} elseif ($command === "start") {$status = "running";echo "Process started\n";} else {echo "Unknown command: $command\n";}
}
?>
PHP;// 创建一个临时文件来存储 PHP 代码
$tempFile = tempnam(sys_get_temp_dir(), 'phpcode');
file_put_contents($tempFile, $phpCode);$descriptorspec = array(0 => array("pipe", "r"), // stdin 是一个管道,由子进程读取1 => array("pipe", "w"), // stdout 是一个管道,由子进程写入2 => array("pipe", "w") // stderr 是一个管道,由子进程写入
);// 启动子进程
$process = proc_open("php $tempFile", $descriptorspec, $pipes);if (is_resource($process)) {// 设置 stdout 为非阻塞模式stream_set_blocking($pipes[1], false);// 父进程:发送指令给子进程并读取输出function sendCommand($pipes, $command) {fwrite($pipes[0], $command . "\n");fflush($pipes[0]); // 确保数据被发送$output = '';$timeout = 2; // 超时时间(秒)$start_time = time();// 使用 fgets 逐行读取子进程的输出while (true) {$line = fgets($pipes[1]);if ($line === false) {// 检查是否超时if (time() - $start_time > $timeout) {break;}usleep(100000); // 等待子进程处理} else {$output .= $line;if (strpos($line, "\n") !== false) {break;}}}return $output;}echo sendCommand($pipes, "status");echo sendCommand($pipes, "start");echo sendCommand($pipes, "status");echo sendCommand($pipes, "stop");// 关闭管道fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);// 关闭子进程并获取退出码$return_value = proc_close($process);// 删除临时文件unlink($tempFile);echo "Command returned $return_value\n";
}
?>