我有一个流程正在侦听事件:terminate
和start
。当我收到一个开始时,我做了:
process = multiprocessing.Process(target=flowGenerator.keepSending,kwargs=(params))
process.daemon = True
process.start()
self.process = process
然后当进程收到terminate
事件时,我会这样做:
if self.process:
if self.process.is_alive():
try:
self.process.terminate()
self.process.join()
except OSError:
pass
self.process = None
但是,如果我之后只有一个start
和terminate
事件。 terminate()函数被锁定在self.process.join()
。到底是怎么回事 ?如果我在每次启动后放置time.sleep(1)
,那么我不会让terminate
发生,然后它永远不会挂起,因此在创建过程中杀死进程时必须遇到一些问题。
我必须补充说process.terminate()
由一个基本上sys.exit(0)
的SIGNAL HANDLER处理。
编辑:
这里我将添加一个完整的示例,该示例是等效的并且具有相同的问题。如果你运行main()两次,它将交给join()
,它与处理信号有关,因为如果我删除它它总是有效。
import time
import multiprocessing
import signal
import sys
import os
class ProcessTest(object):
def __init__(self):
self.process = None
signal.signal(signal.SIGTERM,self.signal_term_handler)
self.parentPid = os.getpid()
def signal_term_handler(self,signal,frame):
if os.getpid() == self.parentPid:
sys.exit(0)
else:
sys.exit(0)
def dummy_function(self):
while True:
time.sleep(5)
def terminate(self):
if self.process and self.process.is_alive():
self.process.terminate()
self.process.join()
self.process = None
def main(self):
self.terminate()
process = multiprocessing.Process(target=self.dummy_function)
process.daemon = True
process.start()
self.process = process
EDIT2:
这里有两个问题:
1)您不能在信号处理程序中使用sys.exit(0)。 sys.exit()
引发异常,因此如果捕获到该异常,则该进程将永远不会完成,并且p.join()将被阻止。
2)更重要也更难。如果您看一下代码,我会一个接一个地调用p.terminate()
和p.join()
。 p.terminate()
会向SIGTERM
发送一个sys.exit()
来调用os._exit()
或更正确p.join()
,但由于信号处理程序在一个线程中运行命令exit
将被调用,如果在信号处理程序中到达var $iframe = $('#iframe');
$iframe.ready(function() {
$iframe.contents().find("body").append($('#mytext'));
});
命令之前发生这种情况,它将永远挂起。
我怎样才能解决问题2?