0

親プロセスが子プロセスを終了しようとしたときに、子プロセスでコードを実行する方法があるかどうかを知りたいです。多分を書く方法はありExceptionますか?

私のコードは次のようになります。

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ただし、子プロセスが終了する前に親プロセスに送信したい。returnどういうわけか親プロセスにすることはできますか?

更新:モジュールの仕組みrunDispatcher()を説明しましょうpysnmp

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 トラップ リスナーを作成することは可能ですか? 適切なリソースを教えてもらえますか?

4

2 に答える 2

2

.runDispatcher() メソッドは実際には非同期 I/O エンジン (asyncore/twisted) のメインループを呼び出します。このメインループは、アクティブな pysnmp の「ジョブ」が保留されなくなるとすぐに終了します。

メインループから定期的に呼び出される独自のコールバック タイマー関数を登録することで、pysnmp ディスパッチャをアプリの残りの部分と連携させることができます。コールバック関数で、終了イベントが到着したかどうかを確認し、pysnmp の「ジョブ」をリセットして、pysnmp メインループを完了させることができます。

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 コアに伝えることを意味します。潜在的に多くのアプリの最後の 1 つが I/O コア操作に関心を持たなくなると、メインループは終了します。

于 2014-03-13T19:55:49.467 に答える
0

子プロセスが協力する可能性がある場合は、終了する必要があり、親に送信するために使用できることを子プロセスmultiprocessing.Eventに通知するために使用できます。multiprocessing.PipeitemToSend

#!/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()

出力

[DEBUG/MainProcess] created semlock with handle 139845842845696
[DEBUG/MainProcess] created semlock with handle 139845842841600
[DEBUG/MainProcess] created semlock with handle 139845842837504
[DEBUG/MainProcess] created semlock with handle 139845842833408
[DEBUG/MainProcess] created semlock with handle 139845842829312
[INFO/Process-1] child process calling self.run()
[INFO/Process-1] sending
{'tosend': 'from child'}
[INFO/Process-1] process shutting down
[DEBUG/Process-1] running all "atexit" finalizers with priority >= 0
[DEBUG/Process-1] running the remaining "atexit" finalizers
[INFO/MainProcess] received
[INFO/Process-1] process exiting with exitcode 0
[INFO/MainProcess] process shutting down
[DEBUG/MainProcess] running all "atexit" finalizers with priority >= 0
[DEBUG/MainProcess] running the remaining "atexit" finalizers
于 2014-03-12T22:17:54.723 に答える