下面是我基於@Sander Visser評論所做的解決方案。關鍵部分是檢查現有的流程,如果有太多
class serialJsonReader{
const MAX_CHILD_PROCESSES = 50;
private $child_processes=[]; //will store alive child PIDs
private function flushCachedDataToStore() {
//resort to single process
if (count($this->child_processes) > self::MAX_CHILD_PROCESSES) {
$this->checkChildProcesses();
$this->storeCollectedData() //main work here
}
//use as much as possible
else {
$pid = pcntl_fork();
if (!$pid) {
$this->storeCollectedData(); //main work here
exit();
}
elseif ($pid == -1) {
die('could not fork');
}
else {
$this->child_processes[] = $pid;
$this->checkChildProcesses();
}
}
}
private function checkChildProcesses() {
if (count($this->child_processes) > self::MAX_CHILD_PROCESSES) {
foreach ($this->child_processes as $key => $pid) {
$res = pcntl_waitpid($pid, $status, WNOHANG);
// If the process has already exited
if ($res == -1 || $res > 0) {
unset($this->child_processes[$key]);
}
}
}
}
}
35訴諸同樣的過程是'EGAIN',這意味着你已經打了進程限制。也許你沒有調用'pcntl_wait'來清理完成後的進程? – Barmar
centos中fork的最大進程數限制是多少?因爲那時它應該是可計算的,200k記錄會發送+/- 200分叉。 「還是有辦法檢查子進程計數」這可以通過保持pid手動完成。一個beter方法將會啓動多個守護進程來獲取一個工作或者運行它proc_open http://php.net/proc_open –
那麼爲什麼分叉可以解決這個問題呢?你正在解析一些數據,然後使用一個單獨的過程同時觸發MySQL - 爲什麼這會成爲解決任何問題的方法?在同一個過程中使用交易有什麼問題?你顯然認爲,如果你分成N個進程,它會快N倍,但不會。現在我們遇到了一個錯誤解決方案的問題,並且解決了這個錯誤的解決方案如果您希望插入速度很快,請在同一事務中對這1000行進行分組。這將花費最少的I/O來編寫。 – Mjh