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)