1

我有一个每分钟运行一次的 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 秒,正如预期的那样。但是,在监视$end2pclose() 时需要大约 60 秒。

看着 htop,进程是可见的,但似乎被暂停了。VM 中有 4 个 CPU 和 16GB RAM,运行时服务器上的负载低于 0.1。在 Ubuntu 11.10 上运行 PHP 5.3.6。

我有一种感觉,这是 OS / PHP 配置上的东西,但 ulimit 是正常的,PHP 内存限制和最大执行时间是无限的。还有什么我应该检查的吗?

4

1 回答 1

1

正如文档所说,“pclose() 函数等待相关进程终止。” 你的设计在很多层面上真的没有任何意义。似乎没有任何理由使用线程或使用popen. 是否有更多代码可以使这些决定变得明智?因为这看起来真的像一个“氢弹杀死蚂蚁”的程序。只需使用fork/ exec

于 2012-08-13T12:41:45.967 回答