Python多处理,重启时终止进程和防止僵尸的问题

Python多处理,重启时终止进程和防止僵尸的问题,python,python-multiprocessing,python-3.5,Python,Python Multiprocessing,Python 3.5,解决方案: 多亏了Rick Sanders,在终止进程后添加此函数可以解决此问题: 僵尸进程是在进程终止时创建的,除非它们被收获(通过请求退出代码)。它们保留的目的是让父级可以请求其退出代码,并且由于我的脚本没有真正退出,它的进程被execv(file,args)替换,父级从不请求退出代码,僵尸进程将保留。这适用于我的OSX和Debian系统 我正在编写一个非常大的脚本,最近实现了多处理和IMAP来监听电子邮件。在实现此功能之前,我已经实现了一个restart命令,我可以在命令行中输入该命令,

解决方案:

多亏了Rick Sanders,在终止进程后添加此函数可以解决此问题:

僵尸进程是在进程终止时创建的,除非它们被收获(通过请求退出代码)。它们保留的目的是让父级可以请求其退出代码,并且由于我的脚本没有真正退出,它的进程被
execv(file,args)
替换,父级从不请求退出代码,僵尸进程将保留。这适用于我的OSX和Debian系统

我正在编写一个非常大的脚本,最近实现了多处理和IMAP来监听电子邮件。在实现此功能之前,我已经实现了一个restart命令,我可以在命令行中输入该命令,以在编辑后刷新脚本,简而言之,它执行以下操作:

if ipt = ':rs':
    execv(__file__)
不过,在这期间,它会打印出一堆废话

我还有一个进程运行在另一个对象中,它在While循环中侦听Google的IMAP服务器,如下所示:

While True:
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    mail.login('myemail@gmail', 'mypassword')
    mail.list()
    mail.select("inbox")

    result, data = mail.uid('search', None, 'All')

    latest_email_uid = data[0].split()[-1] #grabs the most recent email by
                                           #unique id number

    if int(latest_email_uid) != int(last_email_uid): # set earlier from sql                         
                                                     # database
        # do stuff with the mail
    else:
        continue
通过观看top,我注意到我重新启动时正在创建僵尸,所以我创建了一个终止函数:

def process_terminator(self):
    self.imap_listener.terminate()
我在重新启动时称之为:

if ipt == ':rs':
    self.process_object.terminate()
    execv(__file__)
然而,僵尸进程仍然存在。因此,经过几个小时的工作后,我意识到在调用函数后添加time.sleep period并将局部变量设置到进程“exitcode”或打印进程“exitcode”将允许进程终止,即使只需0.1秒:

if ipt == ':rs':
    self.process_object.terminate()
    time.sleep(.1)
    print(self.process_object.imap_listener.exitcode)
    execv(__file__)
不过,OSX中的情况并非如此,只需执行一个进程“.terminate()函数即可结束该进程,但是在我的debian机器上,我必须有一个睡眠(n)周期,并且必须以某种形式或方式引用进程“exitcode”,以防它死机

我也尝试过使用.join,不过这会挂断我的整个脚本。我曾尝试创建变量,使流程在(例如)self.terminated=1时中断其while循环,然后加入,但这也不起作用

我在运行exec('quit')时没有这个问题,只要我终止进程,.join()就不起作用

有人能指出我的误解吗?我尝试过自己做研究,但没有找到足够的解决方案,我知道流程不应该被明确终止,因为它们不会很好地退出,但在工作数小时后,我没有找到其他方法

很抱歉,我没有更多的代码要提供,如果需要,我会尽力提供更多,这些只是我脚本中的相关代码片段(1000多行)。

您可以从这里开始:。父进程必须在其子进程退出时获取它们,例如使用waitpid():


等待特定子进程终止并返回已死亡进程的pid,如果没有此类子进程,则返回-1。在某些系统上,值为0表示仍有进程在运行

啊,这就解释了为什么我必须先读取退出代码,然后才能将其从进程表中删除。我会调整我的代码,看看这是否能解决它。非常感谢。令人惊叹的!这起作用了:
def process_terminator(self):self.imap_listener.terminate()waitpid(self.imap_listener.pid,0)
至少在OSX上,现在将在我的debian系统上试用它。。。