Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.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
是否为Windows调整php并行执行功能?_Php_Windows_Background_Exec_Goroutine - Fatal编程技术网

是否为Windows调整php并行执行功能?

是否为Windows调整php并行执行功能?,php,windows,background,exec,goroutine,Php,Windows,Background,Exec,Goroutine,这是一个并行执行命令数组并返回结果数组的函数,可选地通过回调函数进行过滤,并限制进程数。它在Lion的Mac上运行得非常好: // executes commands in parallel, limited by the number of file descriptors or maxProcesses. // pass an optional callback to filter each result (return a non-null value to stop execution)

这是一个并行执行命令数组并返回结果数组的函数,可选地通过回调函数进行过滤,并限制进程数。它在Lion的Mac上运行得非常好:

// executes commands in parallel, limited by the number of file descriptors or maxProcesses.
// pass an optional callback to filter each result (return a non-null value to stop execution).
function    execParallel($commands, $callback = null, $maxProcesses = PHP_INT_MAX)
{
    $handles = array();
    $results = array();

    for($i = 0; $i < count($commands) || count($handles);)
    {
        if($i < count($commands) && count($handles) < $maxProcesses)
            if(($handle = @popen($commands[$i].' 2> /dev/null &', "r")) !== false)
            {
                stream_set_blocking($handle, 0);    // does nothing on Windows
                $handles[$i] = $handle;
                $results[$i] = '';
                $i++;
            }

        foreach($handles as $key => $handle)
        {
            $results[$key] .= fread($handle, 4096);
            if(feof($handle))
            {
                pclose($handles[$key]);
                unset($handles[$key]);

                if($callback)
                    if($callback($results[$key], $key))
                        break;
            }
        }
    }

    foreach($handles as $key => $handle)    // clear any incomplete tasks
    {
        pclose($handles[$key]);
        unset($handles[$key]);
        unset($results[$key]);
    }

    return $results;
}
输出是一个数字序列,最多128个时间戳,然后大约128个时间戳,这取决于时钟精度以及其他一些进程是否完成。如果出现问题,过滤器可以方便地在中途进行打捞

您可以将进程限制从64更改为1,以查看结果连续到达,或者注释掉$key==128行以防止停止。如果不设置进程数量限制,它将打开尽可能多的进程文件句柄,并等待更多句柄在内部可用

它的工作方式与shell_exec()几乎相同,但在后台启动进程并继续执行。如果您通过关闭句柄过早地关闭了进程,它会将所有关于管道破裂的警告都传递给null

我的问题是,我需要实现跨平台,但无法轻松访问PC或NT等所有Windows操作系统。这是我的待办事项列表:

  • fread()在Windows上阻塞,因为stream_set_blocking()是NOP。也许可以用fread(1)解决这个问题,但它只是伪抢占式的。需要一种方法来查看是否有字节在等待,可以使用select或以不同的方式使流不阻塞
  • 在后台生成进程,可能使用“START/B[command]”。这确实需要与unix中的“&”类似,而不是生成额外的输出、阻塞stout或强制它只能通过文件访问、强制用户创建批处理文件或其他奇怪的东西。它可能需要使用proc_uu()或pcntl_ufork()或其他完全不同的工具,我不太确定
  • 探索使用curl_multi或其他线程工具生成函数,并像往常一样在函数中调用shell_exec()(这需要以不需要安装任何额外库的方式完成)
  • 使用一个好的测试,比如DIRECTORY\u SEPARATOR=='\'在Windows上运行一个单独的代码分支
  • 在Windows上需要一些更好的测试用例,可能是“超时[秒]”或“PING-n[毫秒]127.0.0.1>nul”而不输出
这一切都是从我试图在php中模拟类似于a的东西开始的,在php中,您最多可以生成N个进程,如果您达到某个限制,它就会阻塞,直到有更多可用的进程,然后返回结果。我经常需要加快大型任务的速度,这些任务本来应该很容易并行化,但是php让它变得很困难,因为他们的手被一堆特定于操作系统的细节束缚住了

因此,我认为,无论是谁提出了一个可靠的跨平台版本的这个函数,或是一些非常类似于goroutine的“只工作”的东西,都会发现他们的代码非常受欢迎。我的猜测是,这个函数现在会回到在Windows上连续运行的状态


提前感谢您的帮助,祝您好运

你可以考虑使用<代码> PCTNLXField()和相关函数来实现分叉过程,而不是依赖于用OS特定的shell命令将内容发送到后台。Yo我希望能够在这个例子中像PCTNLYFURK()那样运行命令,但不幸的是Windows没有它。它确实让我想到了这个例子,它在php中创建了一个Com对象,并在后台运行一个命令。有一个限制,它不能启动GUI应用程序,如记事本等,但Mac也这样做安全。我希望有人能在Windows XP/NT/Vista/7上为我测试这个方法。
$commands = array_fill(0, 256, 'sleep 1; echo | date');
$results = execParallel($commands, function($result, $key)
{
    echo "$key\n";
    if($key == 128) return false;
}, 64);
print_r($results);