美文网首页
pcntl_fork 引起的奇怪 bug

pcntl_fork 引起的奇怪 bug

作者: Gundy_ | 来源:发表于2016-06-07 08:58 被阅读1318次

最近随手写了个获取软件最新版本号的程序,但是在处理多进程并发的时候遇到了问题。我想在用户请求的时,输出已经保存的版本号,同时异步抓取最新的版本号。
数据存储用的 redis,在父进程中,与 redis 的通讯没有任何问题,但是在子进程中,与 redis 的通讯就会出现问题,会报类似PHP Notice: Redis::setex(): send of 47 bytes failed with errno=32 Broken pipe in /data/root/api/lib/db.php on line 44
的错误。
搜索后发现,有人遇到了同样的 bug(http://stackoverflow.com/questions/23713480/after-php-upgrade-pcntl-fork-causing-errno-32-broken-pipehttps://github.com/phpredis/phpredis/issues/474),他测试了与 mysql 的通讯,在子进程中并没有问题,怀疑是 redis 的 bug。
既然是子进程的通讯出现了问题,那么在 pcntl_fork
前关闭连接(只有父进程)、在 pcntl_fork
之后关闭连接(父进程和子进程)是否可行呢?测试后发现,果然没再报错,第一个问题解决。

在 php-fpm 中,默认情况下(php-fpm.ini 的默认设置),一个进程(包括 pcntl_fork
产生的子进程)会处理多个请求,所以即使用 exit
结束了脚本,进程也不会退出,pcntl_wait
和 pcntl_waitpid
自然也没用了,只能用 posix_kill(posix_getpid(), SIGTERM);
结束掉当前进程(相当与不带参数的 kill
命令,kill
命令默认发送 SIGTERM 信号)。
虽然子进程结束后,pcntl_wait
和 pcntl_waitpid
都能正常工作,但这两个函数实际上阻塞了父进程,没有起到异步的作用。如果不用这两个函数,当子进程结束时,由于父进程没有回收子进程,导致子进程成为僵尸(defunct)进程,导致系统资源被长时间占用。而且这些进程也不能被 kill
命令结束,只有重启 php-fpm,也就是结束父进程。
要想使父进程不等待子进程,可以通过 pcntl_signal(SIGCLD, SIG_IGN);
或 pcntl_signal(SIGCHLD, SIG_IGN);
(SIGCLD 和 SIGCHLD 都是子进程状态变更的信号,在大部分系统中作用相同;SIG_IGN 忽略该信号)告诉系统:父进程不关心子进程的结束,当子进程结束时,会由 init 进程来回收。
提示:pcntl_signal
是针对父进程设置的,所以在重现这个 bug 时记得重启 php-fpm。

https://github.com/jat001/auto-upgrade-scripts/blob/master/server/lib/db.php#L65

相关文章

  • pcntl_fork 引起的奇怪 bug

    最近随手写了个获取软件最新版本号的程序,但是在处理多进程并发的时候遇到了问题。我想在用户请求的时,输出已经保存的版...

  • 奇怪的“bug”

    今天是1月1日,为了一些事情,我把电脑的时间调到1月10日进行工作。期间我用VS2010发布过我的web程序。发布...

  • 奇怪的bug

    昨天用php curl模拟post发送请求,测试环境一切正常线上却返回了false。 调查了大半天解决了问题,但是...

  • 奇怪的bug

    bug年年有,最近特别多,今天用我的小米笔记本下载点东西,路由器在我面前,却死活连不上,好不容易连上之后显示有In...

  • 奇怪的bug

    1、3S提示,一闪而过:sources——右边暂停按钮 2、动态下拉框定位快捷键:ctrl+shift+C 3、e...

  • rpc引起的bug

    今天算是又增强了自己对pomelo RPC的认识,因为一个bug。起初,我们游戏的角色信息是作为一个redis缓存...

  • getUserId引起的bug

    最近项目中在修改用户昵称的时候报了如下bug 这个问题很眼熟, 上次一个项目也报了。 所以这次记录一下。 原因是a...

  • iOS11 Safe Area的注意点

    iOS11的Safe Area的变化让适配变得很头痛。今天就发现一个奇怪的bug,是由safe area的变化引起...

  • vue 奇怪的Bug

    标题虽然这样起,但是大部分都不是vue的问题,是代码问题 [Vue warn]: $listeners and $...

  • php进程认识

    1、基本认识php系统提供了pcntl_fork 函数来操作进程。pcntl_fork:当前进程位置产生分支(子进...

网友评论

      本文标题:pcntl_fork 引起的奇怪 bug

      本文链接:https://www.haomeiwen.com/subject/vhyddttx.html