PHP多进程编程与进程管理PHP的pcntl扩展提供了多进程编程的能力。虽然Web开发中用得不多但在CLI模式下多进程可以并行处理大量任务。pcntl_fork创建子进程。父进程和子进程在fork之后各自执行不同的代码路径。php// 检查pcntl扩展if (!extension_loaded(pcntl)) {die(pcntl扩展未安装。\n);}if (!extension_loaded(posix)) {die(posix扩展未安装。\n);}echo 父进程 PID: . posix_getpid() . \n;$pid pcntl_fork();if ($pid -1) {die(fork失败\n);} elseif ($pid 0) {// 子进程echo 子进程 PID: . posix_getpid() . , 父进程 PID: . posix_getppid() . \n;for ($i 0; $i 3; $i) {echo 子进程工作... {$i}\n;sleep(1);}exit(0);} else {// 父进程echo 创建了子进程 PID: $pid\n;echo 父进程继续工作\n;pcntl_wait($status); // 等待子进程结束echo 子进程已结束\n;}?多进程并行处理任务可以充分利用多核CPUphpfunction parallelProcess(array $tasks, int $workerCount 4): void{$chunks array_chunk($tasks, ceil(count($tasks) / $workerCount));$children [];foreach ($chunks as $chunkId $taskList) {$pid pcntl_fork();if ($pid -1) {die(fork失败\n);} elseif ($pid 0) {// 子进程echo Worker $chunkId (PID: . posix_getpid() . ) 开始处理 . count($taskList) . 个任务\n;foreach ($taskList as $task) {echo Worker $chunkId 处理: $task\n;sleep(1);}echo Worker $chunkId 完成\n;exit(0);} else {$children[] $pid;}}// 父进程等待所有子进程foreach ($children as $pid) {pcntl_waitpid($pid, $status);echo 子进程 $pid 已退出\n;}echo 所有任务处理完成\n;}$tasks range(1, 20);parallelProcess($tasks, 4);?进程池可以控制并发数量避免一次性创建太多进程phpclass ProcessPool{private int $maxWorkers;private array $workers [];private int $nextId 0;public function __construct(int $maxWorkers 4){$this-maxWorkers $maxWorkers;}public function submit(callable $task, array $args []): int{$this-waitForSlot();$pid pcntl_fork();if ($pid -1) {throw new RuntimeException(fork失败);} elseif ($pid 0) {// 子进程exit($task(...$args) ? 0 : 1);} else {$id $this-nextId;$this-workers[$pid] $id;echo 任务 #$id 已提交 (PID: $pid)\n;return $id;}}public function wait(): void{while (!empty($this-workers)) {$pid pcntl_wait($status);if ($pid 0 isset($this-workers[$pid])) {$id $this-workers[$pid];$exitCode pcntl_wexitstatus($status);echo 任务 #$id 完成 (PID: $pid, 退出码: $exitCode)\n;unset($this-workers[$pid]);}}}private function waitForSlot(): void{while (count($this-workers) $this-maxWorkers) {$pid pcntl_wait($status);if ($pid 0 isset($this-workers[$pid])) {unset($this-workers[$pid]);}}}public function getActiveCount(): int{return count($this-workers);}public function __destruct(){$this-wait();}}$pool new ProcessPool(3);for ($i 1; $i 10; $i) {$pool-submit(function ($id) {$pid posix_getpid();echo 进程 $pid 执行任务 #$id\n;sleep(rand(1, 3));return true;}, [$i]);}$pool-wait();echo 全部完成\n;?进程间通信用消息队列或共享内存php// 简单消息队列class MessageQueue{private int $queue;private int $msgType 1;public function __construct(string $path, int $project){$key ftok($path, $project);if ($key -1) {throw new RuntimeException(ftok失败);}$this-queue msg_get_queue($key);if ($this-queue false) {throw new RuntimeException(获取消息队列失败);}}public function send(mixed $message): bool{return msg_send($this-queue, $this-msgType, serialize($message));}public function receive(): mixed{$message null;$success msg_receive($this-queue, 0, $this-msgType, 65536, $message);return $success ? unserialize($message) : null;}public function remove(): void{msg_remove_queue($this-queue);}public function stats(): array{$stats msg_stat_queue($this-queue);return [messages $stats[msg_qnum],bytes $stats[msg_qbytes],];}}?多进程编程在PHP中需要注意几个问题。子进程会继承父进程的文件描述符和数据库连接需要小心处理。进程退出前要清理资源。信号处理要做好避免出现僵尸进程。总的来说多进程是PHP CLI编程中的重要工具适合数据采集、日志处理、批量计算等场景。
PHP多进程编程与进程管理
PHP多进程编程与进程管理PHP的pcntl扩展提供了多进程编程的能力。虽然Web开发中用得不多但在CLI模式下多进程可以并行处理大量任务。pcntl_fork创建子进程。父进程和子进程在fork之后各自执行不同的代码路径。php// 检查pcntl扩展if (!extension_loaded(pcntl)) {die(pcntl扩展未安装。\n);}if (!extension_loaded(posix)) {die(posix扩展未安装。\n);}echo 父进程 PID: . posix_getpid() . \n;$pid pcntl_fork();if ($pid -1) {die(fork失败\n);} elseif ($pid 0) {// 子进程echo 子进程 PID: . posix_getpid() . , 父进程 PID: . posix_getppid() . \n;for ($i 0; $i 3; $i) {echo 子进程工作... {$i}\n;sleep(1);}exit(0);} else {// 父进程echo 创建了子进程 PID: $pid\n;echo 父进程继续工作\n;pcntl_wait($status); // 等待子进程结束echo 子进程已结束\n;}?多进程并行处理任务可以充分利用多核CPUphpfunction parallelProcess(array $tasks, int $workerCount 4): void{$chunks array_chunk($tasks, ceil(count($tasks) / $workerCount));$children [];foreach ($chunks as $chunkId $taskList) {$pid pcntl_fork();if ($pid -1) {die(fork失败\n);} elseif ($pid 0) {// 子进程echo Worker $chunkId (PID: . posix_getpid() . ) 开始处理 . count($taskList) . 个任务\n;foreach ($taskList as $task) {echo Worker $chunkId 处理: $task\n;sleep(1);}echo Worker $chunkId 完成\n;exit(0);} else {$children[] $pid;}}// 父进程等待所有子进程foreach ($children as $pid) {pcntl_waitpid($pid, $status);echo 子进程 $pid 已退出\n;}echo 所有任务处理完成\n;}$tasks range(1, 20);parallelProcess($tasks, 4);?进程池可以控制并发数量避免一次性创建太多进程phpclass ProcessPool{private int $maxWorkers;private array $workers [];private int $nextId 0;public function __construct(int $maxWorkers 4){$this-maxWorkers $maxWorkers;}public function submit(callable $task, array $args []): int{$this-waitForSlot();$pid pcntl_fork();if ($pid -1) {throw new RuntimeException(fork失败);} elseif ($pid 0) {// 子进程exit($task(...$args) ? 0 : 1);} else {$id $this-nextId;$this-workers[$pid] $id;echo 任务 #$id 已提交 (PID: $pid)\n;return $id;}}public function wait(): void{while (!empty($this-workers)) {$pid pcntl_wait($status);if ($pid 0 isset($this-workers[$pid])) {$id $this-workers[$pid];$exitCode pcntl_wexitstatus($status);echo 任务 #$id 完成 (PID: $pid, 退出码: $exitCode)\n;unset($this-workers[$pid]);}}}private function waitForSlot(): void{while (count($this-workers) $this-maxWorkers) {$pid pcntl_wait($status);if ($pid 0 isset($this-workers[$pid])) {unset($this-workers[$pid]);}}}public function getActiveCount(): int{return count($this-workers);}public function __destruct(){$this-wait();}}$pool new ProcessPool(3);for ($i 1; $i 10; $i) {$pool-submit(function ($id) {$pid posix_getpid();echo 进程 $pid 执行任务 #$id\n;sleep(rand(1, 3));return true;}, [$i]);}$pool-wait();echo 全部完成\n;?进程间通信用消息队列或共享内存php// 简单消息队列class MessageQueue{private int $queue;private int $msgType 1;public function __construct(string $path, int $project){$key ftok($path, $project);if ($key -1) {throw new RuntimeException(ftok失败);}$this-queue msg_get_queue($key);if ($this-queue false) {throw new RuntimeException(获取消息队列失败);}}public function send(mixed $message): bool{return msg_send($this-queue, $this-msgType, serialize($message));}public function receive(): mixed{$message null;$success msg_receive($this-queue, 0, $this-msgType, 65536, $message);return $success ? unserialize($message) : null;}public function remove(): void{msg_remove_queue($this-queue);}public function stats(): array{$stats msg_stat_queue($this-queue);return [messages $stats[msg_qnum],bytes $stats[msg_qbytes],];}}?多进程编程在PHP中需要注意几个问题。子进程会继承父进程的文件描述符和数据库连接需要小心处理。进程退出前要清理资源。信号处理要做好避免出现僵尸进程。总的来说多进程是PHP CLI编程中的重要工具适合数据采集、日志处理、批量计算等场景。