即使退出之前的子进程,也无法 fork 子进程

即使退出之前的子进程,也无法 fork 子进程

我有一台 CentOS VM,上面运行着一个 php 套接字服务器,该服务器在每个连接上都会分叉。子进程完成其工作然后退出。

父进程也在等待收割死去的僵尸进程(我已经检查了ps auxf输出)

pcntl_wait($status, WNOHANG);在每次 fork 之后执行,以便清理 1 个僵尸进程(如果有)

然而,经过长时间运行后,父节点无法分叉。

我认为这是因为32768限制。输出中的进程数ps -auxf始终在 750 左右。

[root@test-machine ~]# cat /proc/self/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             119925               119925               processes
Max open files            1024                 4096                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       119925               119925               signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us


[root@test-machine ~]# cat /proc/sys/kernel/pid_max
32768

更新: 我检查了日志,发现错误信息如下PHP Fatal error: Maximum execution time of 30 seconds exceeded in myfile.php

它指向的行是pcntl_wait($status, WNOHANG);,用于等待子进程终止。WNOHANG标志确保它不会挂起,因此如果没有退出的子进程,它将继续执行。

虽然“最大时间”可以更改,但有些东西会导致pcntl_wait循环。我认为操作系统上的某些东西导致了这种情况的发生。这是具有最大连接的套接字(我有多个套接字,只有这个受到影响)

答案1

我检查了函数 prcntl_wait 的 PHP 文档并发现了这一点:

选项

如果您的系统(主要是 BSD 风格的系统)上可以使用 wait3,则可以提供可选的 options 参数。如果未提供此参数,则 wait 将用于系统调用。如果 wait3 不可用,则提供 options 的值将不起作用。options 的值是以下两个常量中的零个或多个的值,并进行 OR 运算:

可能是您的操作系统没有 wait3,这导致了这个问题。也许您可以更改功能,pcntl_waitpid这样就可以解决您的问题。

相关内容