我有一个PHP脚本,我在Ubuntu linux机器上运行。该脚本使用pcntl_fork()
函数生成多个进程,并使用pcntl_waitpid()
函数记录它们被杀死的情况。它经常产生这些非常(我估计大约40-50 /秒),但是这些过程都会立即被杀死(我已经尝试了exit()
和{{ 1}},无济于事。该脚本可以正常工作几秒钟(取决于10~30秒),但不可避免地会停止并停止创建“子”进程。由于脚本导致计算机上的内存使用量没有增加,但是当脚本停止时,计算机上的CPU会慢慢激活,直到我强制使用Ctrl-C终止脚本。每个进程都用于解析一行文本,最后将其保存到文件中。出于测试目的,我只是在创建子进程后立即退出。在一次测试中,大约1400个进程在脚本冻结之前成功启动并被杀死,尽管我说这个范围。
我知道机器有一个ulimit,但我相信我读到它限制了并发进程的数量。由于这个脚本一旦创建就会杀死子进程,我对发生的事情感到困惑。以下是我当前ulimit配置(posix_kill(${pid}, SIGKILL)
)的输出:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 29470 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 29470 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
PHP中是否存在全局限制,用于确定脚本执行期间创建的进程总数? **请记住,这些子进程会立即被终止,因此我不认为这是一个无限数量的进程正在窃取系统资源的问题。
以下是一些源代码:
我用这个
初始化fork$this->process_control->fork(array($this, "${FUNCTION_NAME}"), array(STRING_LINE), false);
分叉功能。在这种情况下,$ callback是要在适当的类中调用的函数的名称。 $ params是要传递给$ callback中指定的函数的参数数组。
public function fork ($callback, $params = null, $hang = true) { $this->logger->write_log('log', "Entered fork function!"); // Evaluate the return value of the fork switch ($pid = pcntl_fork()) { case -1: // Failed $this->logger->write_log('error', "Could not fork!"); exit(1); break; case 0: // Child created succesfully $this->logger->write_log('log', "Entered child function!"); $this->logger->write_log('log', 'child ' . posix_getpid() . ' started'); if (empty($callback)) { $this->logger->write_log('warn', "Callback empty, nothing to do!"); exit(1); } if (is_array($callback) && is_array($params)) { if (!call_user_func_array($callback, $params)) { $this->logger->write_log('error', "Daemonized process returned false!"); exit(1); } else { exit(0); } } else { if (!call_user_func($callback, $params)) { $this->logger->write_log('error', "Daemonized process returned false!"); exit(1); } else { exit(0); } } break; default: // Parent $this->logger->write_log('log', "Entered parent function!"); if ($hang != true) { $this->wait($pid, false); } else { $this->wait($pid); } break; } } public function wait($p_id, $hang = true) { if ($hang) { $pid = pcntl_waitpid($p_id, $status); } else { $pid = pcntl_waitpid($p_id, $status, WNOHANG); } switch($pid) { case -1: case 0: $this->logger->write_log('log', "child exited"); break; default: $this->logger->write_log('log', "child $pid exited"); break; } }
实际处理文本行的函数。文本行是JSON对象:
public function FUNCTION_NAME($line) { $this->logger->write_log('info', 'entered FUNCTION_NAME function'); $start_time = microtime(true); try { # check to see that the JSON line is not malformed $line_array = json_decode($line, true); if (!isset($line_array)) { throw new Exception('Could not successfully process line'); } # save the contents to disk if (!file_put_contents(FILE_NAME, $line, LOCK_EX)) { throw new Exception('file could not be saved'); } $this->logger->write_log('info', 'saved line'); return true; } catch (Exception $e) { $this->logger->write_log('error', $e->getMessage()); $this->logger->write_log('error', '----------------------------------------------------'); $this->logger->write_log('error', var_export($line, true)); $this->logger->write_log('error', '----------------------------------------------------'); file_put_contents(ERROR_SRC_FILE, $line, FILE_APPEND); return false; } }
很抱歉,如果代码太多,请告诉我任何问题
答案 0 :(得分:1)
要回答原始问题,我没有发现使用php创建的进程数量有限制,只要它们在创建后很快被杀死。我相信用户可以在linux中创建进程的限制,可以使用ulimit
进行设置。