2014-10-16 14 views
9

Tôi có một quy trình Python để sinh ra 5 quy trình Python khác bằng cách sử dụng mô-đun đa xử lý. Hãy gọi quá trình cha mẹ P0 và những người khác P1-P5. Yêu cầu là, nếu chúng ta gửi một SIGTERM đến P0, nó sẽ đóng P1 đến P5 trước và sau đó thoát ra khỏi chính nó.Làm thế nào để một quá trình python thoát ra một cách duyên dáng sau khi nhận được SIGTERM trong khi chờ đợi trên một semaphore?

Bắt là P1 và P5 đang chờ trên semaphores. Vì vậy, khi tôi gửi SIGTERM cho các quá trình này, chúng gọi trình xử lý tín hiệu và thoát. Nhưng vì họ đang chờ đợi trên semaphore, họ ném một ngoại lệ. Có cách nào để nắm bắt ngoại lệ đó trước khi thoát, để P0 đến P5 có thể thực hiện một lối thoát duyên dáng?

Traceback:

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() 
+0

Bạn đang sử dụng phiên bản Python nào? Cuộc gọi cụ thể nào P1 và P5 thực sự khiến họ chờ đợi trên semaphore? Bạn có thể bao gồm các tracebacks? – dano

+1

Một mẫu mã tối thiểu tái tạo vấn đề của bạn sẽ rất tuyệt. –

+0

Tôi đang sử dụng Python 2.7.8 P1 đến P5 đang cố gắng truy cập vào hàng đợi được chia sẻ qua các quy trình và quyền truy cập vào hàng đợi được bảo vệ bằng semaphore.Một cái gì đó như thế này: sem.acquire() item = q.get() sem.release() –

Trả lời

13

Bạn có thể cài đặt một xử lý tín hiệu đó ném một ngoại lệ mà sau đó được đánh bắt trong tiến trình con để xử lý thoát một cách duyên dáng.

Dưới đây là ví dụ về tập lệnh chờ trong semaphore trong quy trình con và chấm dứt một cách duyên dáng khi được gửi 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() 

Một ví dụ chạy của kịch bản này là như sau:

$ ./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 

Không có traceback từ tiến trình con và dòng chảy cho thấy lối ra subprocess một cách duyên dáng. Điều này là do SIGTERM bị bắt bởi trình xử lý tín hiệu con xử lý mà ném một ngoại lệ Python bình thường có thể được xử lý bên trong tiến trình.

Các vấn đề liên quan