这只是一个测试脚本。我正在测试基本的子fork功能,然后创建一个简单的lib,让我产生多个进程来在php中并行处理数据批处理。在继续之前还有其他我应该测试的东西吗?我知道所有资源都是在fork期间复制的,所以初始化/打开fork之后所需的所有资源。
<?php
$childcount = 10;
for($i = 1; $i <= $childcount; $i ++)
{
$pid = pcntl_fork();
if ($pid == -1) {
echo "failed to fork on loop $i of forking\n";
} else if ($pid) {
// we are the parent
$pidArray[$pid] = $pid;
// and we want to wait on all children at the end of the loop
} else {
// we are the child
echo "Child is outputting it's count and dying. Count: $i \n ";
doMessage($i);
die;
}
}
echo "sleeping to see if child finished events queue\n";
sleep(10);
print_r($pidArray);
for($j = 1; $j <= $childcount; $j++)
{
echo "parent is waiting on child\n";
$pid = pcntl_wait($status); //Wait for random child to finish
$pidArray[$pid] = "terminated";
echo "parent found $j of the finished children\n";
}
print_r($pidArray);
function doMessage($location)
{
sleep (rand(4,20));
echo "outputting concurrently : $location \n";
}
输出如下:
me@myhost:~/$]: php test.php
sleeping to see if child finished events queue
Child is outputting it's count and dying. Count: 3
Child is outputting it's count and dying. Count: 4
Child is outputting it's count and dying. Count: 5
Child is outputting it's count and dying. Count: 6
Child is outputting it's count and dying. Count: 8
Child is outputting it's count and dying. Count: 9
Child is outputting it's count and dying. Count: 10
Child is outputting it's count and dying. Count: 7
Child is outputting it's count and dying. Count: 2
Child is outputting it's count and dying. Count: 1
outputting concurrently : 9
outputting concurrently : 1
outputting concurrently : 6
Array
(
[22700] => 22700
[22701] => 22701
[22702] => 22702
[22703] => 22703
[22704] => 22704
[22705] => 22705
[22706] => 22706
[22707] => 22707
[22708] => 22708
[22709] => 22709
)
parent is waiting on child
parent found 1 of the finished children
parent is waiting on child
parent found 2 of the finished children
parent is waiting on child
parent found 3 of the finished children
parent is waiting on child
outputting concurrently : 5
parent found 4 of the finished children
parent is waiting on child
outputting concurrently : 2
parent found 5 of the finished children
parent is waiting on child
outputting concurrently : 3
parent found 6 of the finished children
parent is waiting on child
outputting concurrently : 8
parent found 7 of the finished children
parent is waiting on child
outputting concurrently : 7
parent found 8 of the finished children
parent is waiting on child
outputting concurrently : 4
outputting concurrently : 10
parent found 9 of the finished children
parent is waiting on child
parent found 10 of the finished children
Array
(
[22700] => terminated
[22701] => terminated
[22702] => terminated
[22703] => terminated
[22704] => terminated
[22705] => terminated
[22706] => terminated
[22707] => terminated
[22708] => terminated
[22709] => terminated
)
我还确认另外一个pctl_wait将立即返回,pid为-1。
答案 0 :(得分:1)
您的示例不会触及您可以使用pcntl_fork加密的问题。
请记住,fork()会复制程序,这意味着会复制所有描述符。不幸的是,对于PHP程序来说这是一个相当糟糕的情况,因为大多数描述符都是由PHP或PHP扩展内部处理的。
解决这个问题的简单,可能是“正确”的方法是先分叉,确实不需要在程序中的许多不同点进行分叉,你只需要fork,然后委托工作。使用主/工作层次结构。
例如,如果你需要有许多使用MySQL连接的进程,只需在建立连接之前进行fork,那么每个子进程都有自己与mysql的连接,并且只有它自己管理。
另一件需要注意的事情是儿童过程何时死亡。死亡应由父母处理。如果不是,那么孩子就变成了僵尸:它不消耗资源,但它仍然是一个带有PID的过程。这是不可取的,因为大多数(全部?)操作系统对其可以处理的进程有一个上限。
当孩子死亡时,会向父母(SIGCHLD)发送信号。然后,父母可以处理孩子的死亡以进行内部处理。解密孩子的正确方法是使用pcntl_waitpid()。您可以使用该功能等待孩子死亡,或者检测到孩子已经死亡。如果要为无数个孩子执行此操作,请使用pcntl_wait()。查看PHP手册的相关部分以获取更多选项(包括让函数知道不要暂停正常操作)。
然而,使用SIGCHLD并不总是万无一失。当您快速创建许多短期子项时,与pcntl_waitpid()一起处理SIGCHLD可能无法处理所有僵尸进程。
希望这有帮助,php.net上的文档是可以的,但在我看来,由于这些功能很容易被误用,因此可能会更深入地讨论主题和潜在的陷阱。
这是一个简单的例子(从php.net评论中删除),它显示了将资源分配给父线程的错误:
<?php
mysql_connect(/* enter a working server here maybe? */);
$f=pcntl_fork();
while(true){
sleep(rand(0,10)/100);
$r=mysql_query("select $f;");
if(!$r)die($f.": ".mysql_error()."\n");
list($x)=mysql_fetch_array($r);
echo ($f)?".":"-";
if($x!=$f) echo ($f.": fail: $x!=$f\n ");
}
?>
在cli上运行此功能将会产生不同的结果:
经常只是挂起而不再输出任何东西
也常常会关闭连接,可能是因为它接收到无法处理的交错请求。
有时一个进程会获得OTHER进程的结果 查询! (因为它们都在同一个套接字上发送查询, 得到答复的是纯粹的运气)
希望当您扩展示例以获取数据和/或使用资源时,这会有所帮助。
快乐的意识!