amphp/parallel
是一个可以在PHP中并行处理任务的库。你可以使用它来启动和管理子进程。
核心代码:
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";
}
?>