我的问题是这样的。我正在分叉一个进程,以便可以加快磁盘上文件的访问时间。我将这些文件中的所有数据存储在本地桌面上的 tmp 文件中。理想情况下,在所有进程完成后,我需要访问该 tmp 文件并将该数据放入数组中。然后我取消链接 tmp 文件,因为不再需要它。我的问题是, pcntl_wait() 似乎并没有真正等到所有子进程完成后才继续进行最后一组操作。因此,我最终在某个随机过程完成之前取消了该文件的链接。
我似乎无法找到一种可靠的方法来等待所有进程完全退出然后访问我的数据。
$numChild = 0;
$maxChild = 20; // max number of forked processes.
// get a list of "availableCabs"
foreach ($availableCabs as $cab) {
// fork the process
$pids[$numChild] = pcntl_fork();
if (!$pids[$numChild]) {
// do some work
exit(0);
} else {
$numChild++;
if ($numChild == $maxChild) {
pcntl_wait($status);
$numChild--;
}
} // end fork
}
// Below is where things fall apart. I need to be able to print the complete serialized data. but several child processes don't actually exit before i unlink the file.
$dataFile = fopen($pid, 'r');
while(($values = fgetcsv($dataFile,',')) !== FALSE) {
$fvalues[] = $values;
}
print serialize($fvalues);
fclose($dataFile);
unlink($file);
请注意,我遗漏了很多关于我实际在做什么的代码,如果我们需要发布那不是问题。
尝试重构代码,以便有两个循环 - 一个生成进程,另一个等待进程完成。您还应该使用pcntl_waitpid() http://uk.php.net/manual/en/function.pcntl-waitpid.php检查特定进程 ID,而不是您当前使用的简单子进程计数方法。
像这样的事情:
<?php
$maxChildren = 20; // Max number of forked processes
$pids = array(); // Child process tracking array
// Get a list of "availableCabs"
foreach ($availableCabs as $cab) {
// Limit the number of child processes
// If $maxChildren or more processes exist, wait until one exits
if (count($pids) >= $maxChildren) {
$pid = pcntl_waitpid(-1, $status);
unset($pids[$pid]); // Remove PID that exited from the list
}
// Fork the process
$pid = pcntl_fork();
if ($pid) { // Parent
if ($pid < 0) {
// Unable to fork process, handle error here
continue;
} else {
// Add child PID to tracker array
// Use PID as key for easy use of unset()
$pids[$pid] = $pid;
}
} else { // Child
// If you aren't doing this already, consider using include() here - it
// will keep the code in the parent script more readable and separate
// the logic for the parent and children
exit(0);
}
}
// Now wait for the child processes to exit. This approach may seem overly
// simple, but because of the way it works it will have the effect of
// waiting until the last process exits and pretty much no longer
foreach ($pids as $pid) {
pcntl_waitpid($pid, $status);
unset($pids[$pid]);
}
// Now the parent process can do it's cleanup of the results
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)