僵尸状态多处理库python3
我的问题是在使用python3的多处理库时,替换join()函数以避免已终止进程的失效或僵化状态。是否有一种替代方案可以暂停终止子进程,直到它们从主进程获得绿灯?这允许它们在不进入僵尸状态的情况下正确终止 我使用以下代码准备了一个快速说明,该代码启动了20个不同的进程,第一个进程需要10秒的加载工作,而所有其他进程需要3秒的加载工作:僵尸状态多处理库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
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
。。。
#僵尸需要的资源比挂起但未终止的进程少。挂起一个进程而不是让它变成僵尸是完全适得其反的。如果在进程完成工作后挂起该进程,则不会占用任何资源,至少在程序员方面是这样。我的意图是让脚本完全控制进程,而不是让操作系统通过其假设来控制我的代码,特别是不管是否终止进程!谢谢,我发现队列方法真的很有趣,它使用队列增加了一些负载,但要保持一致性。