Trong chương trình Python đa luồng, một luồng đôi khi yêu cầu đầu vào bảng điều khiển bằng cách sử dụng được xây dựng trong raw_input(). Tôi muốn có thể đóng chương trình trong khi tại dấu nhắc raw_input bằng cách gõ^C vào vỏ (tức là, với tín hiệu SIGINT). Tuy nhiên, khi thread con đang thực thi raw_input, gõ^C không làm gì cả - KeyboardInterrupt không được nâng lên cho đến khi tôi nhấn return (để lại raw_input).Ngắt Python raw_input() trong một chuỗi con với^C/KeyboardInterrupt
Ví dụ, trong các chương trình sau đây:
import threading
class T(threading.Thread):
def run(self):
x = raw_input()
print x
if __name__ == '__main__':
t = T()
t.start()
t.join()
Typing^C không có gì cho đến sau khi đầu vào là xong. Tuy nhiên, nếu chúng tôi chỉ gọi T().run()
(nghĩa là trường hợp chỉ có một luồng: chỉ cần chạy raw_input trong chuỗi chính),^C sẽ đóng chương trình ngay lập tức.
Có lẽ, điều này là do SIGINT được gửi đến chủ đề chính, bị treo (chờ GIL) trong khi các chuỗi được chia nhỏ trên bàn điều khiển đọc. Các chủ đề chính không nhận được để thực hiện xử lý tín hiệu của nó cho đến khi nó lấy GIL sau khi raw_input trả về. (Xin vui lòng sửa tôi nếu tôi sai về điều này - Tôi không phải là chuyên gia về việc triển khai luồng của Python.)
Có cách nào để đọc từ stdin theo cách giống như raw_input trong khi cho phép xử lý SIGINT bởi sợi chính và do đó làm giảm toàn bộ quá trình?
[Tôi đã quan sát hành vi nêu trên Mac OS X và một vài Linuxes khác nhau.]
Edit: Tôi đã mischaracterized vấn đề cơ bản ở trên. Khi điều tra thêm, đó là lời kêu gọi của chủ đề chính tới join()
đang ngăn chặn việc xử lý tín hiệu: chính Guido van Rossum đã giải thích rằng the underlying lock acquire in join is uninterruptible. Điều này có nghĩa là tín hiệu thực sự bị trì hoãn cho đến khi toàn bộ chuỗi kết thúc - vì vậy điều này thực sự không liên quan gì đến raw_input
(chỉ thực tế là luồng nền đang chặn để kết nối không hoàn thành).
Không chỉ đơn giản là kết hợp Chủ đề và gián đoạn ... [boromir.jpg] – JBernardo