栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

坑跌的gevent,fork,进程无法获取退出状态

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

坑跌的gevent,fork,进程无法获取退出状态

这个点下班真实罪恶

今天一个跑了好久的一个项目突然gg,程序执行到一半抛了个mysql异常,误以为连接超时,搞了半天排除不是mysql问题。

加log后发现是子进程退出时其他进程获取不到状态,导致程序阻塞,一直等待子进程退出。关键是一模一样的代码另一台机器上完全没问题,查询python版本也完全一致

当时并未想到是第三方模块的问题。尝试了多种方式都无法通知其他进程,开始以为是子进程之间无法通信,写了测试代码,并没有问题。然后就开始撸项目代码,突然看到另一个函数子进程可以正常退出并通知,对比下一个是gevent.sleep, 一个是time.sleep,文件头引入了from gevent import monkey; monkey.patch_os(),把monkey注释掉,程序竟然正常运行了

测试发现,使用patch_os后,os.fork就会被gevent.fork,此时循环阻塞如果是time.sleep,就永远获取不到进程状态,改成gevent.sleep 程序又能正常运行,两种解决方案都可

对比了两台机器环境发现问题版本是gevent 1.1.1,正常 gevent 1.0.1,想起来之前做另一个项目时升级过包版本,果然是跳出来的猴子,

纪录下引以为戒。涉及进程协程的代码,尽量保持一致,另外python3 真香远离python2

测试代码

import os,time,gevent
from gevent import monkey; monkey.patch_os()
def fork2():
    pid = os.fork()
    if pid == 0:
        print "11111",os.getpid()
    else:
        print "00000",os.getpid()
        res = os.waitpid(pid, os.WNOHANG)
        print "id2 res",res
    if pid == 0:
        time.sleep(1)
        print "exit id2",os.getpid()
        os._exit(0)
    else:
        time.sleep(5)
        print "id2",pid
        res = os.waitpid(pid, os.WNOHANG)
        time.sleep(2)
        print "id2 res",res

def fork1():
    pid = os.fork()
    if pid == 0:
        print "id1",os.getpid()
        fork2()
        os._exit(0)
    else:
        print "id0",os.getppid()
        res = os.waitpid(pid, os.WNOHANG)
        print "id1 res", res
        while res == (0,0) :
            print 6666
            res = os.waitpid(pid, os.WNOHANG)
            print "id1 res", res
            if res != (0,0):
                break
            time.sleep(1)
fork1()
print "end"
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878762.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号