PHP中的全局进程生成限制?

时间:2012-04-16 14:53:15

标签: php linux process limit ulimit

我有一个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;
        }
    }

很抱歉,如果代码太多,请告诉我任何问题

1 个答案:

答案 0 :(得分:1)

要回答原始问题,我没有发现使用php创建的进程数量有限制,只要它们在创建后很快被杀死。我相信用户可以在linux中创建进程的限制,可以使用ulimit进行设置。