Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Symfony2流程组件-无法创建管道并启动新流程_Php_Symfony_Process_Symfony Process - Fatal编程技术网

Php Symfony2流程组件-无法创建管道并启动新流程

Php Symfony2流程组件-无法创建管道并启动新流程,php,symfony,process,symfony-process,Php,Symfony,Process,Symfony Process,我正在使用Symfony2流程组件手动管理一个流程池 在下面的示例中,我每2秒重新启动2个简单进程,并监视发生的情况。重新启动这些进程数百次后,应用程序将中断 执行已停止,我收到以下PHP警告: proc_open(): unable to create pipe Too many open files 然后Symfony进程组件引发以下异常: [Symfony\Component\Process\Exception\RuntimeException] Unable to launch a

我正在使用Symfony2流程组件手动管理一个流程池

在下面的示例中,我每2秒重新启动2个简单进程,并监视发生的情况。重新启动这些进程数百次后,应用程序将中断

执行已停止,我收到以下PHP警告:

proc_open(): unable to create pipe Too many open files
然后Symfony进程组件引发以下异常:

[Symfony\Component\Process\Exception\RuntimeException]  
Unable to launch a new process.   
我已经手动监控了打开进程的总数,但它从未超过预期的限制

下面的简化代码段是Symfony2命令的一部分,正在从CLI运行(例如,app/console仓鼠:run):

此应用程序正在运行OS X 10.8.4的MAC服务器上运行

如果有任何关于如何从根本上解决这个问题的提示,我将不胜感激

更新#1:我简化了我的功能,可以使用诸如
ls
date
之类的基本命令进行快速测试。在启动和停止大约1000-1500个进程之后,进程命令似乎仍然失败


我怀疑没有为每个进程正确调用
proc\u close()
,但进一步的调查显示,情况并非如此。

文件句柄没有被垃圾收集,因此它们最终会被填满(os limit或php limit,不确定),但您可以通过添加一个:

另外,请注意,垃圾收集在
foreach
循环中无法很好地工作,因为php将临时
$foo映射为$bar=>$var
数组变量到内存中。如果您在代码的这一部分需要它,您可以将其切换为类似的内容,我认为这应该允许在
for
循环中进行垃圾收集:

$processes[] = new Process("ls > /dev/null", null, null, null, 2);
$processes[] = new Process("date > /dev/null", null, null, null, 2);

$sleep = 0;

do {
    $count = count($processes);
    for($i = 0; $i < $count; $i++) {
        if (!$processes[$i]->isStarted()) {
            $processes[$i]->start();

            continue;
        }

        try {
            $processes[$i]->checkTimeout();
        } catch (\Exception $e) {
            // Don't stop main thread execution
        }

        if (!$processes[$i]->isRunning()) {
            // All processes are timed out after 2 seconds and restarted afterwards
            $processes[$i]->restart();
        }

        gc_collect_cycles();
    }

    usleep($sleep * 1000000);
} while ($count > 0);
$processs[]=新进程(“ls>/dev/null”,null,null,null,2);
$processs[]=新流程(“日期>/dev/null”,null,null,null,2);
$sleep=0;
做{
$count=计数($processs);
对于($i=0;$i<$count;$i++){
if(!$processs[$i]->isStart()){
$processs[$i]->start();
继续;
}
试一试{
$processs[$i]->checkTimeout();
}捕获(\异常$e){
//不要停止主线程执行
}
if(!$processs[$i]->isRunning()){
//所有进程在2秒后超时,然后重新启动
$processs[$i]->restart();
}
gc_collect_cycles();
}
美国LEEP(睡眠*1000000美元);
}而($count>0);

这一点很好。我没有考虑手动调用垃圾收集器的必要性。使用
gc\u collect\u cycles()
执行一些额外的基准测试(重启进程100000多次)确认了您的解决方案。谢谢一个更好的方法是停止(0)进程实例。完成后,这将有效地关闭打开的文件描述符,而不必依赖垃圾收集器调用的
\uu destruct
。你用它救了我的命!需要睡觉吗?
gc_collect_cycles();
usleep($sleep * 1000000);
$processes[] = new Process("ls > /dev/null", null, null, null, 2);
$processes[] = new Process("date > /dev/null", null, null, null, 2);

$sleep = 0;

do {
    $count = count($processes);
    for($i = 0; $i < $count; $i++) {
        if (!$processes[$i]->isStarted()) {
            $processes[$i]->start();

            continue;
        }

        try {
            $processes[$i]->checkTimeout();
        } catch (\Exception $e) {
            // Don't stop main thread execution
        }

        if (!$processes[$i]->isRunning()) {
            // All processes are timed out after 2 seconds and restarted afterwards
            $processes[$i]->restart();
        }

        gc_collect_cycles();
    }

    usleep($sleep * 1000000);
} while ($count > 0);