2011-07-19 35 views
5

HẠN Tôi có một ví dụ đơn giản:chương trình Twisted và tín hiệu

 
    from twisted.internet import utils,reactor 

    def test: 
     utils.getProcessOutput(executable="/bin/sleep",args=["10000"]) 

    reactor.callWhenRunning(test) 
    reactor.run() 

khi tôi gửi tín hiệu "TERM" để chương trình "ngủ" tiếp tục được thực hiện, khi tôi nhấn Ctrl-C trên bàn phím "ngủ "dừng lại. (Ctrl-C không phải là tín hiệu tương đương TERM?) Tại sao? Làm thế nào để giết "giấc ngủ" sau khi gửi tín hiệu "TERM" cho chương trình này?

Trả lời

4

Ctrl-C gửi SIGINT đến toàn bộ nhóm tiến trình nền trước. Điều đó có nghĩa là nó được gửi đến chương trình Twisted của bạn và cho quá trình con ngủ.

Nếu bạn muốn giết quá trình giấc ngủ bất cứ khi nào quá trình Python sẽ thoát ra, sau đó bạn có thể muốn có một trước khi tắt máy kích hoạt:

def killSleep(): 
    # Do it, somehow 

reactor.addSystemEventTrigger('before', 'shutdown', killSleep) 

Như ví dụ mã của bạn được viết, killSleep rất khó để triển khai thực hiện. getProcessOutput không cung cấp cho bạn một cái gì đó dễ dàng cho phép trẻ bị giết (ví dụ, bạn không biết pid của nó). Nếu bạn sử dụng reactor.spawnProcess và tùy chỉnh ProcessProtocol, sự cố này được giải quyết - ProcessProtocol sẽ được kết nối với quá trình vận chuyển có phương thức signalProcess mà bạn có thể sử dụng để gửi SIGTERM (hoặc bất kỳ thứ gì bạn thích) cho quy trình con.

Bạn cũng có thể bỏ qua SIGINT và thời điểm này và sau đó tự đưa nó vào nhóm toàn bộ quá trình:

import os, signal 

def killGroup(): 
    signal.signal(signal.SIGINT, signal.SIG_IGN) 
    os.kill(-os.getpgid(os.getpid()), signal.SIGINT) 

reactor.addSystemEventTrigger('before', 'shutdown', killGroup) 

Bỏ qua SIGINT vì quá trình Twisted đã được tắt và tín hiệu khác sẽ không làm bất cứ tốt (và có lẽ sẽ gây nhầm lẫn hoặc ít nhất dẫn đến các lỗi giả mạo được báo cáo). Gửi tín hiệu đến -os.getpgid(os.getpid()) là cách gửi tín hiệu đến toàn bộ nhóm quy trình của bạn.

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