Nếu tôi có một chuỗi trong một vòng lặp vô hạn, có cách nào để kết thúc nó khi chương trình chính kết thúc (ví dụ: khi tôi nhấn Ctrl+ C) không?
Câu trả lời:
Kiểm tra câu hỏi này. Câu trả lời đúng có lời giải thích tuyệt vời về cách kết thúc luồng đúng cách: Có cách nào để giết một luồng trong Python không?
Để làm cho chuỗi dừng trên tín hiệu Ngắt bàn phím (ctrl + c), bạn có thể bắt ngoại lệ "KeyboardInterrupt" và dọn dẹp trước khi thoát. Như thế này:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
Bằng cách này, bạn có thể kiểm soát những việc cần làm bất cứ khi nào chương trình bị chấm dứt đột ngột.
Bạn cũng có thể sử dụng mô-đun tín hiệu tích hợp cho phép bạn thiết lập bộ xử lý tín hiệu (trong trường hợp cụ thể của bạn là tín hiệu SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()
một chức năng toàn cục mà tôi có thể sử dụng? hay tôi cần phải thực hiện nó?
Nếu bạn tạo luồng công nhân của mình là các luồng daemon, chúng sẽ chết khi tất cả các luồng không phải là daemon của bạn (ví dụ: luồng chính) đã thoát.
http://docs.python.org/library/threading.html#threading.Thread.daemon
isDaemon()
là False, hãy đặt nó là True setDaemon(True)
.
isDaemon()
và setDaemon()
đang thu khí cũ / setters (theo doc liên kết ở trên), chỉ cần sử dụng daemon=True
trongthreading.Thread()
Thử kích hoạt tiểu trình dưới dạng daemon-thread.
Khuyến nghị:
from threading import Thread
t = Thread(target=<your-method>)
t.daemon = True # This thread dies when main thread (only non-daemon thread) exits.
t.start()
Nội tuyến:
t = Thread(target=<your-method>, daemon=True).start()
API cũ:
t.setDaemon(True)
t.start()
Khi luồng chính của bạn kết thúc ("tức là khi tôi nhấn Ctrl+ C"), các luồng khác cũng sẽ bị giết theo hướng dẫn ở trên.
Sử dụng mô-đun atexit của thư viện tiêu chuẩn của Python để đăng ký các hàm "kết thúc" được gọi (trên luồng chính) trên bất kỳ kết thúc "sạch" hợp lý nào của luồng chính, bao gồm một ngoại lệ không cần thiết, chẳng hạn như KeyboardInterrupt
. Các hàm kết thúc như vậy có thể (mặc dù không thể tránh khỏi trong chuỗi chính!) Gọi bất kỳ stop
hàm nào bạn yêu cầu; cùng với khả năng thiết lập một chủ đề daemon
, cung cấp cho bạn các công cụ để thiết kế đúng chức năng hệ thống mà bạn cần.
atexit.register()
lệnh gọi sau khi thực hiện trong mô-đun Python, khiến thủ tục kết thúc của bạn được thực thi sau lệnh multiprocessing
gọi. Tôi gặp sự cố này khi xử lý Queue
và daemon
chủ đề: “Lỗi EOF” khi thoát chương trình bằng cách sử dụng Hàng đợi và Luồng đa xử lý .
atexit
trình xử lý không được gọi khi các luồng không phải daemon còn sống và luồng chính thoát. Xem Tập lệnh bị kẹt khi thoát khi sử dụng atexit để kết thúc chuỗi .
Nếu bạn sinh ra một Chủ đề như vậy - myThread = Thread(target = function)
- và sau đó làm myThread.start(); myThread.join()
. Khi CTRL-C được bắt đầu, luồng chính sẽ không thoát vì nó đang chờ myThread.join()
lệnh gọi chặn đó . Để khắc phục điều này, chỉ cần đặt thời gian chờ cho cuộc gọi .join (). Thời gian chờ có thể kéo dài như bạn muốn. Nếu bạn muốn nó đợi vô thời hạn, chỉ cần đặt một khoảng thời gian chờ thực sự dài, chẳng hạn như 99999. Bạn cũng nên làm myThread.daemon = True
như vậy tất cả các luồng sẽ thoát khi luồng chính (không phải daemon) thoát.
myThread.daemon = True
là một giải pháp tuyệt vời cho vấn đề này.
.daemon=True
không phải là dung dịch rắn. Kiểm tra chủ đề này cho một lời giải thích: stackoverflow.com/a/20598791/5562492
Các luồng daemon bị giết một cách không theo quy định nên mọi hướng dẫn của trình hoàn thiện đều không được thực thi. Một giải pháp khả thi là kiểm tra xem luồng chính có còn sống hay không thay vì vòng lặp vô hạn.
Ví dụ: đối với Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
Xem Kiểm tra xem Chủ đề chính có còn tồn tại từ một chủ đề khác không .