是否为Windows调整php并行执行功能?
这是一个并行执行命令数组并返回结果数组的函数,可选地通过回调函数进行过滤,并限制进程数。它在Lion的Mac上运行得非常好:是否为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)
// 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”而不输出
提前感谢您的帮助,祝您好运你可以考虑使用<代码> 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);