Điều này sẽ rất đơn giản và tôi rất ngạc nhiên khi tôi không thể tìm thấy câu hỏi này đã được trả lời trên stackoverflow.Xử lý tín hiệu trong Python đa luồng
Tôi có một daemon giống như chương trình cần đáp ứng với tín hiệu SIGTERM và SIGINT để hoạt động tốt với mới nổi. Tôi đọc rằng cách tốt nhất để làm điều này là để chạy vòng lặp chính của chương trình trong một chủ đề riêng biệt từ các chủ đề chính và để cho các chủ đề chính xử lý các tín hiệu. Sau đó, khi một tín hiệu được nhận, bộ xử lý tín hiệu phải báo cho vòng lặp chính thoát ra bằng cách thiết lập một lá cờ sentinel thường xuyên được kiểm tra trong vòng lặp chính.
Tôi đã thử làm điều này nhưng nó không hoạt động theo cách tôi mong đợi. Xem mã bên dưới:
from threading import Thread
import signal
import time
import sys
stop_requested = False
def sig_handler(signum, frame):
sys.stdout.write("handling signal: %s\n" % signum)
sys.stdout.flush()
global stop_requested
stop_requested = True
def run():
sys.stdout.write("run started\n")
sys.stdout.flush()
while not stop_requested:
time.sleep(2)
sys.stdout.write("run exited\n")
sys.stdout.flush()
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
t = Thread(target=run)
t.start()
t.join()
sys.stdout.write("join completed\n")
sys.stdout.flush()
Tôi thử nghiệm này trong hai cách sau:
1)
$ python main.py > output.txt&
[2] 3204
$ kill -15 3204
2)
$ python main.py
ctrl+c
Trong cả hai trường hợp tôi mong đợi viết này đến đầu ra:
run started
handling signal: 15
run exited
join completed
Trong trường hợp đầu tiên thoát khỏi chương trình nhưng tất cả tôi thấy là:
run started
Trong trường hợp thứ hai tín hiệu SIGTERM được dường như bỏ qua khi ctrl + c được nhấn và chương trình không thoát.
Tôi thiếu gì ở đây?
Thử thay thế 't.join()' bằng 'while t.is_alive(): t.join (1)'. Chủ đề chính của bạn sẽ thức dậy mỗi giây để kiểm tra tín hiệu. – roippi
Đọc thêm: http://snakesthatbite.blogspot.com/2010/09/cpython-threading-interrupting.html – roippi