我有一个cron作业,它每分钟运行一次,并为多租户应用程序执行内部cron逻辑。 PHP脚本获取每个客户端,它们的域然后自行分叉并在每个客户端“范围”(内部名称)下运行。见下文:
<?php
$i = 0;
foreach($clients as $client) {
$client->get_domains();
foreach($client->domains as $domain) {
$threads[$i]['client'] = $client->id;
$threads[$i]['domain'] = $domain->id;
$i++;
}
}
$pids = array();
foreach($threads as $key => $thread) {
$pids[$key] = pcntl_fork();
if(!$pids[$key]) {
$start = microtime(TRUE);
$handle = popen($args[0] . ' --client ' . $thread['client'] . ' --domain ' . $thread['domain'] . ' 2>&1', 'r');
// $end1 = ~0.001 sec execution time
pclose($handle);
// $end2 = ~60 sec execution time
exit();
}
}
我目前正在将负载迁移到另一台服务器,因此请安装新的Ubuntu 11.04,并像现有机器一样进行设置。应用程序上运行了大约40个域,因此在一秒钟内创建了40个叉。
我的问题是,每个分叉进程只返回TRUE
进程的事件大约需要60秒。
当转储$end1
时间时,popen()大约需要0.001秒,这是预期的。但是,当监视$end2
时,pclose()需要大约60秒。
观看htop,进程可见,但似乎暂停了。 VM中有4个CPU和16GB RAM,运行时服务器上的负载低于0.1。在Ubuntu 11.10上运行PHP 5.3.6。
我觉得它是OS / PHP配置上的东西,但ulimit是正常的,PHP内存限制和最大执行时间是无限的。还有什么我应该检查的吗?
答案 0 :(得分:1)
正如文档所说,“pclose()函数等待关联的进程终止。”你的设计在很多层面上都没有任何意义。似乎没有任何理由使用线程或使用popen
。是否有更多的代码可以使这些决策变得合理?因为这看起来像是一个“杀死蚂蚁的H炸弹”计划。只需使用fork
/ exec
。