当前位置: 首页 > 知识库问答 >
问题:

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

别宏盛
2023-03-14

我有一个PHP脚本,我正在Ubuntu linux机器上运行。该脚本使用<code>pcntl_fork()</code>函数生成多个进程,并使用<code>pcntl _waitpid()</code>函数记录它们被杀死的情况。它经常生成这些进程(我估计大约40-50个/秒),但这些进程都会立即被杀死(我尝试了<code>exit()</code>和<code>posix_kill(${pid},SIGKILL)</code>,但都没有用)。脚本可以正常工作几秒钟(视情况而定,10~30秒),但不可避免地会停止创建“子”进程。脚本导致的机器内存使用不会增加,但当脚本停止时,机器上的cpu会缓慢增加,直到我使用Ctrl-C强制终止脚本。每个过程旨在解析一行文本,并最终将其保存到文件中。出于测试目的,我只是在创建子进程后立即退出它们。在一个测试中,大约1400个进程在脚本冻结之前成功启动和终止,尽管如我所说,这是一个范围。

我知道机器有一个ulimit,但我相信我读到它限制了并发进程的数量。由于这个脚本一创建子进程就杀死它们,所以我对正在发生的事情感到困惑。以下是我当前ulimit配置的输出(ulimit-a):

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个答案

暴奕
2023-03-14

为了回答最初的问题,我没有发现可以使用php创建的进程的数量有限制,只要它们在创建后不久就被杀死。我相信在linux中用户可以创建的进程是有限制的,可以用< code>ulimit来设置。

 类似资料:
  • 尽管分布式熔断在控制分布式系统中的吞吐量方面通常是非常有效的,但是有时并不是非常有效,所以需要全局速率限制。最常见的情况是,大量主机转发请求到少量主机,并且平均请求延迟较低(例如连接到数据库服务器的请求)。如果目标主机被备份,则下游主机将压倒上游集群。在这种情况下,要在每个下游主机上配置足够严格的熔断限制是非常困难的,这样系统将在典型的请求模式期间正常运行,但仍然可以防止系统因发生故障而引发的级联

  • 问题内容: 简介: 我正在开发一个持久性Java Web应用程序,并且我需要确保持久化的所有资源都具有全局唯一标识符,以防止重复。 细则: 我没有使用RDBMS,所以没有任何特殊的序列生成器(例如Oracle提供的序列生成器) 我希望它速度很快,最好是全部在内存中-我宁愿不必打开文件并增加一些值 它必须是线程安全的(我预计一次只需要一个JVM即可生成ID) JVM的各个实例之间必须具有一致性。如果

  • 问题内容: 什么是效用全球关键字? 有什么理由偏爱一种方法而不是另一种方法? 安全? 性能? 还要别的吗? 方法1: 方法2: 什么时候使用有意义? 对我来说,这似乎很危险 ……但可能只是缺乏知识。我对 文档化的 技术原因感兴趣(例如,带有示例代码,链接到文档…)。 提前致谢! 赏金 这是关于该主题的一个很好的一般性问题,我(@Gordon)会提供赏金以获取其他答案。您的答案是否与我的意见一致或给

  • 问题内容: PHP的函数不能提供良好的随机数。因此,我开始使用据说效果更好的产品。但是这些结果有多好?有什么方法可以再次改善它们? 我的点子: 这应该给您“完美的”随机数,不是吗? 问题答案: 伪随机数生成器(PRNG)是非常复杂的野兽。 没有真正的“完美”随机数生成器-实际上,可以通过数学函数完成的最好的操作是伪随机数-对于大多数意图和目的,它们似乎足够随机。 实际上,从PRNG返回的数字中执行

  • 这一章,我们将学会如何在PHP扩展中使用全局变量。 在扩展中定义全局变量 首先,我们需要在扩展的头文件中(默认是php_*.h)中定义所有的全局变量。举个例子,比如我们要定义一个无符号的long类型的全局变量,我们可以这样定义: ZEND_BEGIN_MODULE_GLOBALS(sample4) unsigned long counter; ZEND_END_MODULE_GLOBALS

  • 如果我想为一些oauth的东西做一个函数,我可以在视图或控制器中使用它(想想rails,你在应用程序控制器中做)。 我阅读的所有内容都说明要创建一个helpers文件夹并在那里添加函数,然后您可以这样做这是正确的方法吗? 创建可用于刀片模板和控制器的辅助函数的“laravel方式”是什么?