12

multiprocessing モジュールを使用して、他の 5 つの Python プロセスを生成する Python プロセスがあります。親プロセスを P0 と呼び、その他を P1 ~ P5 と呼びましょう。要件は、SIGTERM を P0 に送信する場合、最初に P1 から P5 をシャットダウンしてから終了することです。

問題は、P1 と P5 がセマフォで待機していることです。したがって、これらのプロセスに SIGTERM を送信すると、プロセスはシグナル ハンドラを呼び出して終了します。しかし、セマフォで待機しているため、例外がスローされます。P0 から P5 が正常に終了できるように、終了前にその例外をキャッチする方法はありますか?

トレースバック:

Traceback (most recent call last):
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
Traceback (most recent call last):
Process Process-2:
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
Traceback (most recent call last):
self.run()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
Process Process-5:
Traceback (most recent call last):
File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
  self.run()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 114, in run
  self._target(*self._args, **self._kwargs)
File "/opt/fireeye/scripts/mip/StaticAnalysisRunner.py", line 45, in run
  qsem.acquire()
4

1 に答える 1

15

例外をスローするシグナルハンドラーをインストールして、サブプロセスでキャッチされ、終了を適切に処理できます。

サブプロセスのセマフォで待機し、SIGTERM.

#!/usr/bin/env python

import signal
import time
import multiprocessing

class GracefulExit(Exception):
    pass


def signal_handler(signum, frame):
    raise GracefulExit()


def subprocess_function():
    try:
        sem = multiprocessing.Semaphore()
        print "Acquiring semaphore"
        sem.acquire()
        print "Semaphore acquired"

        print "Blocking on semaphore - waiting for SIGTERM"
        sem.acquire()
    except GracefulExit:
        print "Subprocess exiting gracefully"


if __name__ == "__main__":

    # Use signal handler to throw exception which can be caught to allow
    # graceful exit.
    signal.signal(signal.SIGTERM, signal_handler)

    # Start a subprocess and wait for it to terminate.
    p = multiprocessing.Process(target=subprocess_function)
    p.start()

    print "Subprocess pid: %d" % p.pid

    p.join()

このスクリプトの実行例は次のとおりです。

$ ./test.py 
Subprocess pid: 7546
Acquiring semaphore
Semaphore acquired
Blocking on semaphore - waiting for SIGTERM
----> Use another shell to kill -TERM 7546
Subprocess exiting gracefully

サブプロセスからのトレースバックはなく、フローはサブプロセスが正常に終了したことを示しています。これは、プロセス内で処理できる通常の Python 例外をスローするサブプロセス シグナル ハンドラによって SIGTERM がキャッチされるためです。

于 2014-10-17T03:13:11.300 に答える