僵尸状态多处理库python3

僵尸状态多处理库python3,python,python-3.x,python-multiprocessing,zombie-process,Python,Python 3.x,Python Multiprocessing,Zombie Process,我的问题是在使用python3的多处理库时,替换join()函数以避免已终止进程的失效或僵化状态。是否有一种替代方案可以暂停终止子进程,直到它们从主进程获得绿灯?这允许它们在不进入僵尸状态的情况下正确终止 我使用以下代码准备了一个快速说明,该代码启动了20个不同的进程,第一个进程需要10秒的加载工作,而所有其他进程需要3秒的加载工作: import os import sys import time import multiprocessing as mp from multiprocessin

我的问题是在使用python3的多处理库时,替换join()函数以避免已终止进程的失效或僵化状态。是否有一种替代方案可以暂停终止子进程,直到它们从主进程获得绿灯?这允许它们在不进入僵尸状态的情况下正确终止

我使用以下代码准备了一个快速说明,该代码启动了20个不同的进程,第一个进程需要10秒的加载工作,而所有其他进程需要3秒的加载工作:

import os
import sys
import time
import multiprocessing as mp
from multiprocessing import Process

def exe(i):
    print(i)    
    if i == 1:
        time.sleep(10)
    else:
        time.sleep(3)
procs = []
for i in range(1,20):
    proc = Process(target=exe, args=(i,))
    proc.start()
    procs.append(proc)

for proc in procs:
    print(proc) # <-- I'm blocked to join others till the first process finishes its work load
    proc.join()

print("finished")
导入操作系统
导入系统
导入时间
将多处理作为mp导入
从多处理导入进程
def exe(i):
印刷品(一)
如果i==1:
时间。睡眠(10)
其他:
时间。睡眠(3)
过程=[]
对于范围(1,20)内的i:
proc=Process(target=exe,args=(i,))
程序启动()
过程追加(proc)
对于进程中的进程:
打印(proc)#Per,Marko Rauhamaa写道:

如果不想知道子进程何时退出,可以忽略SIGCHLD信号:

import signal
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
这将防止僵尸出现

报告解释说:

POSIX.1-2001规定,如果SIGCHLD的处置设置为 为SIGCHLD设置SIG_IGN或SAU NOCLDWAIT标志(请参阅 sigaction(2)),则终止的子对象不会变成僵尸,并且 对wait()或waitpid()的调用将被阻止,直到所有子项 终止,然后在errno设置为ECHILD时失败。(原文) POSIX标准保留了将SIGCHLD设置为SIG_IGN的行为 未指定。请注意,即使 SIGCHLD是“忽略”,显式地将处置设置为SIG_IGN 僵尸过程儿童的不同治疗结果。)

Linux 2.6符合POSIX要求。但是,Linux 2.4 (和更早的版本)没有:如果在 SIGCHLD被忽略,调用的行为就像SIGCHLD一样 没有被忽略,也就是说,调用会一直阻塞到下一个子级 终止,然后返回该子进程的进程ID和状态

因此,如果您使用的是Linux 2.6或兼容POSIX的操作系统,那么使用上述代码将允许子进程退出而不会变成僵尸。如果您没有使用与POSIX兼容的操作系统,那么上面的线程提供了许多选项。下面是一个备选方案,与Marko Rauhamaa的方案有些相似


如果出于某种原因,您需要知道子进程何时退出并希望 以不同的方式处理(至少其中一些),然后您可以设置一个队列 允许子进程在完成时向主进程发送信号。然后 主进程可以按照接收的顺序调用适当的联接 队列中的项目:

import time
import multiprocessing as mp

def exe(i, q):
    try:
        print(i)    
        if i == 1:
            time.sleep(10)
        elif i == 10:
            raise Exception('I quit')
        else:
            time.sleep(3)
    finally:
        q.put(mp.current_process().name)

if __name__ == '__main__':
    procs = dict()
    q = mp.Queue()
    for i in range(1,20):
        proc = mp.Process(target=exe, args=(i, q))
        proc.start()
        procs[proc.name] = proc

    while procs:
        name = q.get()
        proc = procs[name]
        print(proc) 
        proc.join()
        del procs[name]

    print("finished")
产生如下结果

...    
<Process(Process-10, stopped[1])>  # <-- process with exception still gets joined
19
<Process(Process-2, started)>
<Process(Process-4, stopped)>
<Process(Process-6, started)>
<Process(Process-5, stopped)>
<Process(Process-3, stopped)>
<Process(Process-9, started)>
<Process(Process-7, stopped)>
<Process(Process-8, started)>
<Process(Process-13, started)>
<Process(Process-12, stopped)>
<Process(Process-11, stopped)>
<Process(Process-16, started)>
<Process(Process-15, stopped)>
<Process(Process-17, stopped)>
<Process(Process-14, stopped)>
<Process(Process-18, started)>
<Process(Process-19, stopped)>
<Process(Process-1, started)>      # <-- Process-1 ends last
finished
。。。

#僵尸需要的资源比挂起但未终止的进程少。挂起一个进程而不是让它变成僵尸是完全适得其反的。如果在进程完成工作后挂起该进程,则不会占用任何资源,至少在程序员方面是这样。我的意图是让脚本完全控制进程,而不是让操作系统通过其假设来控制我的代码,特别是不管是否终止进程!谢谢,我发现队列方法真的很有趣,它使用队列增加了一些负载,但要保持一致性。