1 信號的意義
在linux系統中信號是與進程通信的一種手段。假設沒有信號,linux中的進程一旦運行起來將不再受控,這種局面對於進程的管理來說是一種災難。kill、ctrl+c等操作本質上就是我們向linux發出的信號,進程接收到信號后根據相應的策略做出反饋。
2 信號的來源
A) 通過終端(組合鍵)產生信號
最典型的ctrl+c終止當前進程
B) 硬件異常產生信號
例如進程運行中內存的尋址出現異常,就會發出信號。
C) 顯式的調用linux命令產生信號
最典型的kill命令,通過linux命令發出信號干預進程運行
D) 軟件代碼發送信號
Java本地方法、Python signal類包等,通過程序發出信號。
3 有哪些信號
執行命令$kill -l可以看到信號列表

可以看到有62種信號,32、33輪空;1-31號為不可靠信號,是linux自帶的與進程通信的信號;34-64是可靠信號,是為了彌補linux不可靠信號太少而擴展的。不可靠信號多次發出最終只響應1次;而可靠信號每次都有響應。
執行命令$man 7 signal可以更詳細的查看每一種信號的意義:

例如我們前面說過的ctrl+c,對應的是2號sigint;kill對應的是9號sigkill;內存錯誤對應的11號sigsegv。
4 進程會如何處理這些信號
並不是每種信號進程都要給出反饋的,進程對待信號會有3種策略:
A) 忽略此信號
好理解,就是假裝沒看見,不鳥它。
B) 執行默認動作
例如終止進程等
C) 提供一個信號處理函數,要求內核執行該函數
通過某種形式在發送信號時同時給定處理信號的函數,相當於回調函數
5 python對信號的支持
Python對信號的操作在importsignal這個包里,有了前面知識的積累,我們很好理解signal包調用的側重點:哪種信號?如何處理?如何發送?
A) 哪種信號?
Linux的62種信號,signal包已經都搬到python中來了,需要開發人員自己選擇一種
B) 如何處理?
Signal默認提供了Ignal和Default2種策略,同時支持開發人員自定義回調函數
C) 如何發送?
Signal對信號的發送做了簡易的封裝,例如alarm()函數發起sigalrm信號
6 案例,做一個timeout的自定義annotation:
import signal def timeout(seconds=10, error_message="connect to server timeout"): def decorator(func): def _handle_timeout(signum, frame): raise TimeoutError(error_message) def wrapper(*args, **kwargs): signal.signal(signal.SIGALRM, _handle_timeout) signal.alarm(seconds) try: result = func(*args, **kwargs) finally: signal.alarm(0) return result return wraps(func)(wrapper) return decorator
先定制了一個回調函數decorator,超時后直接拋異常;
然后通過signal.signal()方法決定了信號種類和處理方式,第一個參數可以替換成62種信號的其中一種,第二個參數還可以傳入SIG_DFL或SIG_IGN;
最后通過signal.alarm()函數發起信號。
這樣我就自己開發了一個超時處理機制。
@timeout(1200) def ready_host(**not_connected): while True: if not any(not_connected): break for h in not_connected.keys(): if check_port_is_open(h): del not_connected[h] return True ———————————————— 版權聲明:本文為CSDN博主「牛麥康納」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/yejingtao703/article/details/80659458
原文鏈接:https://blog.csdn.net/yejingtao703/article/details/80659458
