Exception 当终止发生时,python多处理在子进程中执行代码
我想知道当父进程试图终止子进程时,是否有办法在子进程上运行一些代码。我们有没有办法写一个Exception 当终止发生时,python多处理在子进程中执行代码,exception,python-2.7,return,multiprocessing,pysnmp,Exception,Python 2.7,Return,Multiprocessing,Pysnmp,我想知道当父进程试图终止子进程时,是否有办法在子进程上运行一些代码。我们有没有办法写一个异常也许 我的代码如下所示: main_process.py import Process from multiprocessing def main(): p1 = Process(target = child, args = (arg1, )) p1.start() p1.daemon = True #blah blah blah code here sleep
异常
也许
我的代码如下所示:
main_process.py
import Process from multiprocessing
def main():
p1 = Process(target = child, args = (arg1, ))
p1.start()
p1.daemon = True
#blah blah blah code here
sleep(5)
p1.terminate()
def child(arg1):
#blah blah blah
itemToSend = {}
#more blah blah
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
由于作业从未完成,子进程将继续运行。我必须从父进程终止它,因为子进程永远不会自行终止。但是,我想在子进程终止之前将itemToSend
发送到父进程。我是否可以以某种方式将其返回父进程
更新:让我解释一下pysnmp
模块的runDispatcher()
是如何工作的
def runDispatcher():
while jobsArePending(): # jobs are always pending because of jobStarted() function
loop()
def jobStarted(jobId):
if jobId in jobs: #This way there's always 1 job remaining
jobs[jobId] = jobs[jobId] + 1
这是非常令人沮丧的。我们是否可以自己编写一个snmp陷阱监听器来代替所有这些工作?你能给我指出正确的资源吗?如果子进程可以合作,那么你可以使用多处理.Event
通知子进程它应该退出并多处理。管道可以用来将itemToSend
发送给父进程:
#!/usr/bin/env python
import logging
import multiprocessing as mp
from threading import Timer
def child(stopped_event, conn):
while not stopped_event.wait(1):
pass
mp.get_logger().info("sending")
conn.send({'tosend': 'from child'})
conn.close()
def terminate(process, stopped_event, conn):
stopped_event.set() # nudge child process
Timer(5, do_terminate, [process]).start()
try:
print(conn.recv()) # get value from the child
mp.get_logger().info("received")
except EOFError:
mp.get_logger().info("eof")
def do_terminate(process):
if process.is_alive():
mp.get_logger().info("terminating")
process.terminate()
if __name__ == "__main__":
mp.log_to_stderr().setLevel(logging.DEBUG)
parent_conn, child_conn = mp.Pipe(duplex=False)
event = mp.Event()
p = mp.Process(target=child, args=[event, child_conn])
p.start()
child_conn.close() # child must be the only one with it opened
Timer(3, terminate, [p, event, parent_conn]).start()
输出
.runDispatcher()方法实际上调用异步I/O引擎(asyncore/twisted)的主循环,该引擎在没有挂起的活动pysnmp“作业”时立即终止
您可以通过注册自己的回调计时器函数,使pysnmp dispatcher与应用程序的其余部分协作,该函数将定期从mainloop调用。在回调函数中,您可以检查终止事件是否到达,并重置pysnmp“作业”,这将使pysnmp mainloop完成
def timerCb(timeNow):
if terminationRequestedFlag: # this flag is raised by an event from parent process
# use the same jobId as in jobStarted()
snmpEngine.transportDispatcher.jobFinished(1)
snmpEngine.transportDispatcher.registerTimerCbFun(timerCb)
这些pysnmp作业只是标志(如代码中的“1”),意味着告诉I/O核心异步应用程序仍然需要这个I/O核心来运行和服务它们。一旦许多应用程序中的最后一个对I/O核心操作不再感兴趣,主循环就会终止。@Alp我恐怕这两个问题的答案都是“是”。snmpEngine.transportDispatcher.runDispatcher()函数无限期运行。它从不停止。停止它的唯一方法是终止整个过程。但是我需要子进程将运行runDispatcher()
时计算的itemToSend
发送回父进程。@user25111458:在子进程的后台守护进程线程中运行runDispatcher
,等待stopped\u事件
并在最后发送itemToSend
。@J.F.Sebastian抱歉,我忘了提到我的子进程是一个守护进程。和守护进程不允许具有children@user2511458谢谢你的回复。如果没有runDispatcher()
函数,这个解决方案将非常有效。子进程中的while
循环永远不会执行,因为runDispatcher()
不会在不终止进程的情况下退出。
def timerCb(timeNow):
if terminationRequestedFlag: # this flag is raised by an event from parent process
# use the same jobId as in jobStarted()
snmpEngine.transportDispatcher.jobFinished(1)
snmpEngine.transportDispatcher.registerTimerCbFun(timerCb)