我有以下 PHP 脚本。我需要用 5 个不同的子进程执行 5 个不同的任务(使用 pcntl_fork() 函数)。 Childs 被正确创建并且他们做他们的事情,但似乎他们永远不会退出。 parent 等待他们结束,但它从未发生过。谁能告诉我我做错了什么?
<?php
for ($i=1; $i<=5; $i++) {
$pid = pcntl_fork();
if ($pid == -1) {
die("Error Creating subprocess ".$i);
exit(-1);
}
else if (!$pid) {
switch ($i) {
case 1:
// Child 1
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 2:
// Child 2
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 3:
// Child 3
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 4:
// Child 4
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 5:
// Child 5
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
default:
break;
}
}
else {
$pids[] = $pid;
}
}
error_log("Luke, I\'m your father. PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
foreach ($pids as $key => $child) {
$res = pcntl_waitpid($child, $status);
//Check if this child has exited normally
if (pcntl_wifexited($status))
error_log("Child ".$child." has ended\n", 3, "/var/log/php_errors.log");
else
error_log("Child ".$child." is zombie\n", 3, "/var/log/php_errors.log");
if($res == -1 || $res > 0)
unset($pids[$key]);
}
?>
最佳答案
<?php
for ($i=1; $i<=5; $i++) {
$pid = pcntl_fork();
if ($pid == -1) {
die("Error Creating subprocess ".$i);
exit(-1);
}
else if (!$pid) {
switch ($i) {
case 1:
// Child 1
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 2:
// Child 2
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 3:
// Child 3
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 4:
// Child 4
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
case 5:
// Child 5
error_log("I\'m the child number ".$i." PID: ".getmypid()."\n", 3, "/var/log/php_errors.log");
//Doing some stuff
exit;
default:
break;
}
}
else {
$pids[$pid] = $pid;
}
}
while (!empty($pids)) {
if ($child = pcntl_wait($status, WNOHANG)) {
if (pcntl_wifexited($status))
error_log("Child ".$child." has ended\n", 3, "/var/log/php_errors.log");
else
error_log("Child ".$child." is zombie\n", 3, "/var/log/php_errors.log");
unset($pids[$child]);
} else
usleep(100);
}
不要忘记更改 $pids[] = $pid;到 $pids[$pid] = $pid; :o) 或选择更好的方式从退出的数组中弹出。
关于PHP - 子进程未正确退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26507939/