Thư viện tín hiệu Python cho phép chúng tôi tương tác với các tín hiệu cấp hệ điều hành cho các sự kiện không đồng bộ và xử lý chúng bằng Trình xử lý tín hiệu tùy chỉnh. Ví dụ: nếu chúng ta nhấn CTRL + C trong khi thực hiện chương trình, thao tác này sẽ kết thúc quá trình thực thi chương trình. Đây là những gì chúng ta gọi là một sự kiện
Cùng với những sự kiện này, hệ điều hành tạo ra một “tín hiệu” để cho chúng tôi biết sự kiện đã xảy ra. Mô-đun tín hiệu trong Python cho phép chúng tôi vượt qua các hành vi mặc định của các sự kiện này bằng Xử lý tín hiệu tùy chỉnh của riêng chúng tôi
Giới thiệu về Tín hiệu Python
Đây là những tín hiệu hiện có trên Windows [kể từ Python 3. 10]. Nếu bạn đang sử dụng Hệ điều hành dựa trên Unix, chẳng hạn như MacOS hoặc Linux, bạn có thể thấy nhiều Tín hiệu hơn có sẵn cho mình [Windows không hỗ trợ tất cả]
Chúng tôi có thể sử dụng đoạn mã sau để in ra danh sách các tín hiệu có sẵn trên hệ điều hành của chúng tôi. Mỗi tín hiệu cũng có một ID số nguyên duy nhất, có thể được sử dụng để xác định nó
import signal valid_signals = signal.valid_signals[] print[valid_signals]
{, , , , , , }
Ghi chú. Có một số tín hiệu chỉ có trên Windows
Để biết danh sách đầy đủ các tín hiệu và mô tả tương ứng của chúng, bạn nên tham khảo tài liệu thực tế về các tín hiệu Python
Sử dụng Trình xử lý tín hiệu
Như chúng tôi đã đề cập trước đó, bạn có thể “xử lý” một tín hiệu để thay đổi hành vi mặc định của nó. Hãy sử dụng SIGINT, kích hoạt khi bạn gọi CTRL + C [trong khi thực thi chương trình]
Để “xử lý” một tín hiệu như SIGINT, chúng ta cần sử dụng hàm signal[] từ module tín hiệu như hình bên dưới
signal.signal[signal.SIGINT, signal_handler]
Tham số đầu tiên là tín hiệu mà chúng ta muốn xử lý và tham số thứ hai là tên của hàm mà chúng ta muốn xử lý. Hàm này được tự động truyền hai tham số, tham số đầu tiên là ID tín hiệu và tham số thứ hai là chi tiết khung
Nếu chúng tôi kích hoạt SIGINT ở trạng thái mặc định, chương trình sẽ kết thúc. Hãy để chúng tôi thử và thay đổi hành vi này và làm cho nó đơn giản in ra một câu lệnh thông thường
import signal import time # Our signal handler def signal_handler[signum, frame]: print["Signal ID:", signum, " Frame: ", frame] # Handling SIGINT signal.signal[signal.SIGINT, signal_handler] time.sleep[5]
Đoạn mã trên sẽ làm cho chương trình ngủ trong 5 giây. Tuy nhiên, điều này sẽ không ngăn bạn kích hoạt CTRL + C [SIGINT], vì đây là một sự kiện không đồng bộ. Trong 5 giây này, nếu chúng ta nhấn các phím CTRL + C, thì chúng ta sẽ nhận được đầu ra sau
Signal ID: 2 Frame:
Cũng cần lưu ý rằng CTRL + C sẽ không đóng chương trình của chúng tôi vì chúng tôi đã thay đổi hành vi của nó
Xử lý tín hiệu nâng cao trong Python
Có nhiều hàm khác có sẵn trong thư viện signal[] cho phép chúng ta dễ dàng kích hoạt và xử lý tín hiệu tốt hơn. Hãy để chúng tôi thảo luận về một số tín hiệu quan trọng hơn, cũng như một số tín hiệu khác có sẵn cho chúng tôi
Một điều thú vị mà chúng ta có thể làm là giữ nguyên original_handler cho hàm SIGINT. Bất cứ khi nào bạn chỉ định một tín hiệu tùy chỉnh bằng cách sử dụng hàm signal[]
, thực tế sẽ có một hàm được trả về, có thể được sử dụng để gọi trình xử lý ban đầu
Chúng tôi có thể sử dụng điều này để cuối cùng khôi phục SIGINT về hành vi mặc định của nó [bằng cách chuyển nó vào chức năng tín hiệu] hoặc chúng tôi có thể sử dụng nó như một chức năng thông thường bên trong trình xử lý tín hiệu của mình, cho phép chúng tôi sử dụng hành vi tùy chỉnh cùng với hành vi mặc định
import signal import time # Our signal handler def signal_handler[signum, frame]: global original_handler print["Signal ID:", signum, " Frame: ", frame] original_handler[signum, frame] original_handler = signal.signal[signal.SIGINT, signal_handler] print["Waiting for 5 seconds..."] time.sleep[5]
Hãy thử chạy đoạn mã trên. Bạn sẽ nhận được cả câu lệnh in [hành vi tùy chỉnh] và ngắt bàn phím [hành vi mặc định]
Một chức năng tiện dụng khác mà chúng ta có thể sử dụng là chức năng báo thức [], tạo tín hiệu SIGALRM. Điều gì làm cho chức năng này trở nên đặc biệt? . Điều này mang lại cho chúng tôi rất nhiều cơ hội để lên lịch các sự kiện và chức năng
import signal import time def signal_handler[signum, stack]: print['Alarm: ', time.ctime[]] signal.signal[signal.SIGALRM, signal_handler] signal.alarm[5] time.sleep[10]
Thời gian. lệnh gọi sleep[] là cần thiết, nếu không thì chương trình của chúng ta sẽ kết thúc trước khi SIGALRM có một thay đổi để kích hoạt