美文网首页
使用subprocess中Popen造成管道死锁问题排查记录

使用subprocess中Popen造成管道死锁问题排查记录

作者: 氕氘氚0921 | 来源:发表于2019-09-29 13:57 被阅读0次

    问题现象

    在程序中使用了uwsgi的stats功能,使用Popen打开新的进程,执行:

    uwsgi --connect-adn-read /home/tmp/stats
    

    程序会在一段时间内发生假死。

    分析与处理

    被创建子进程在开始运行时,它的stdout, stderr已被重定向到管道里面了。Linux里的管道都会有一定的容量,当道管满了写执行write操作就会block,直到可以写为止。在上面的代码里,父进程创建子进程后,没有对它们通信的管道进行read操,而是调用 wait 等待子进程结束。如果子进程把输出写满了管道,那它会非常希望父进程尽快把它清理掉;而父进程此时在希望子进程尽快结束。
    错误代码如下所示

    process = Popen(args=emperor_arguments, stdout=PIPE, stderr=PIPE)
    process.wait()
    

    在python的Popen的官方文档中可以看到,推荐使用 Popen.communicate()。这个方法会把输出放在内存,而不是管道里,所以这时候上限就和内存大小有关了,一般不会有问题。而且如果要获得程序返回值,可以在调用 Popen.communicate() 之后取 Popen.returncode 的值。
    修改后的代码如下:

    process = Popen(args=emperor_arguments, stdout=PIPE, stderr=PIPE)    
    stdoutdata, stderrdata = process.communicate()
    

    经测试问题已经处理。

    参考资料

    https://blog.csdn.net/linyt/article/details/2983960

    相关文章

      网友评论

          本文标题:使用subprocess中Popen造成管道死锁问题排查记录

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