等待所有的PID在PHP中退出 [英] waiting for all pids to exit in php
问题描述
我的问题是这个.我正在分叉一个进程,以便可以加快对磁盘上文件的访问时间.我将这些文件中的所有数据存储在本地桌面上的tmp文件中.理想情况下,在所有进程完成之后,我需要访问该tmp文件并将该数据放入一个数组中.然后,我取消链接tmp文件,因为不再需要它.我的问题是pcntl_wait()似乎并没有严格地等待所有子进程完成后才继续进行最后一组操作.因此,我最终会在完成一些随机过程之前取消链接该文件.
My issue is this. I am forking a process so that I can speed up access time to files on disk. I store any data from these files in a tmp file on local desk. ideally, after all processes have finished, I need to access that tmp file and get that data into an array. I then unlink the tmp file as it is no longer needed. My problem is that it would seem that pcntl_wait() does not acutally wait until all child processes are done before moving on to the final set of operations. So I end up unlinking that file before some random process can finish up.
我似乎找不到一种可靠的方法来等待所有进程完全退出然后访问我的数据.
I can't seem to find a solid way to wait for all processes to exit cleanly and then access my data.
$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);
请注意,如果我们需要发布的那不是问题,那么我会遗漏大量有关我实际在做什么的代码.
please note that i'm leaving a lot of code out regarding what i'm actually doing, if we need that posted thats not issue.
推荐答案
尝试重组代码,以便有两个循环-一个循环产生进程,另一个循环等待进程完成.您还应该使用 pcntl_waitpid()
检查特定的进程ID ,而不是您当前使用的简单的子计数方法.
Try restructuring you code so that you have two loops - one that spawns processes and one that waits for them to finish. You should also use pcntl_waitpid()
to check for specific process IDs, rather than the simple child counting approach you are currently using.
类似这样的东西:
<?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
这篇关于等待所有的PID在PHP中退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!