wiki signalgithub
SIGCHID: signal child
shell
當子進程終止、被中斷或者被中斷後恢復,SIGCHID
信號被髮送到父進程,該信號的常見用法是:指示操做系統在子進程終止後,清理子進程使用的資源django
SIGHUB: signal hangup
安全
當控制終端被關閉時候,SIGHUB
信號被髮送到父進程,它最初設計用於通知串行線路中斷(掛斷)的過程,在現代操做系統中,SIGHUB
信號一般意味着控制僞終端或者虛擬終端已經被關閉,許多守護進程在接到該信號後,將會從新加載它們的配置文件而且從新打開它們的日誌文件,一般不會在收到信號後,退出。使用NOHUP
命令會忽略該信號。ui
注:例如,django web開發環境,直接使用nohup 命令開啓服務,關閉終端不會影響到web server服務spa
SIGQUIT: signal quit
操作系統
由QUIT
字符(一般是Ctrl-
來控制)觸發,進程在收到SIGQUIT
信號退出時候會產生core
文件,在這個意義上相似於一個程序錯誤信號設計
SIGINT: signal interrupt
當用戶但願中斷進程時候,在控制終端按下INTE
字符(一般是Ctrl+C
)後,控制終端將發送信號SIGINT
到其餘進程
SIGTERM: signal termination
terminal
信號被髮送到進程以請求其終止,與SIGKILL
信號不一樣,它能夠被進程捕獲,解釋或者忽略,這容許進程在合適的狀況下執行良好的終止釋放資源和保存狀態,SIGINT
和SIGTERM
幾乎相同
程序結束信號,與SIGKILL
不一樣的是該信號能夠被阻塞和處理,一般用於要求程序本身正常退出,shell命令kill
不帶參數,將產生這個信號,若是進程終止不了,纔會嘗試SIGKILL
SIGKILL: signal kill
kill
信號被髮送到某個進程,使得該進程當即終止,和SIGTERM
和SIGINT
相反,這個信號不能被捕獲或者忽略,而且接收過程在接收到這個信號時候不能執行任何清理,可是下面狀況爲例外:
(1)殭屍進程(zombie
)進程不能被殺死,由於它們已經死了,殭屍進程在等待其父進程捕獲處理;
(2)處於阻塞狀態的進程在再次被喚醒以前不能被殺死;
(3)init
進程是特殊進程,它不接收不想處理的信號,因此它能夠不接收kill
信號,Linux中的ptraced init
進程是例外;
(4)不間斷的睡眠進程可能不會終止(釋放資源),即便接收到SIGKILL
,這是少數的須要從新啓動操做系統,用於解決臨時軟件問題的狀況之一。
在大多數操做系統關機過程當中,SIGKILL
用於終止進程的最後手段,若是SIGTERM
不能主動退出。
爲了更快的關機,Mac OS X 10.6
(雪豹,snow leopard)把SIGKILL
信號發送到被標記爲clean
的應用程序,從而加快這些應用程序的關閉過程,並且估計不會帶來任何不良的影響。
shell命令kill -9
對應着SIGKILL
信號,該命令可能帶有不良影響,由於該命令不容許進程保存未保存的數據,一般使用更加安全的shell命令(kill 不帶參數,即SIGTERM
信號)
SIGTTIN
和 SIGTTOU
後臺進程,試圖從tty
讀取或者寫入時候,全部進程會收到SIGTTIN
, SIGTTOU
信號,一般,該信號僅由做業控制下的進程接收,守護進程沒有控制終端,所以,不會接收到這些信號。
當後臺做業要從用戶終端讀取數據時候,該做業中的全部進程會收到信號
SIGUSR1
和 SIGUSR2
留給用戶使用,信號根據用戶定義的條件發送
SIGWINCH: signal window change
當控制終端窗口大小變化時候,SIGWINCH
信號發送到進程
終端Ctrl-
產生信號SIGQUIT
終端Ctrl-C
產生信號SIGINT
shell命令kill不帶參數
產生信號SIGTERM
shell命令kill -9
產生信號SIGKILL
管道(pipe
),一個管道基本上是內核中的一塊內存,一個由某些進程讀寫的緩衝區,使用管道的優勢是它有兩個相關聯的文件描述符,所以在兩個進程之間共享數據就像是讀寫文件同樣簡單。
import os rfd, wfd = os.pipe() # rfd, wfd = (3, 4) 文件描述符
基本上管道所作的是保留一個內存塊,並返回兩個文件描述符,這些描述符能夠用於從該內存塊中寫入數據和讀取數據。所以,兩個進程間通訊,進程A能夠經過wfd
寫入數據,進程B能夠經過rfd
讀取數據。
例如:cat foobar | wc -l
這將運行2個進程cat foobar
和wc -l
,標準輸出一般被更改成管道的寫入端,wc -l
能夠將其標準輸入更改成管道的讀取端,用於讀取cat foobar
程序輸出的數據。
這種標準輸入、標準輸出(STDIN
和STDOUT
)到管道的變化是由shell
進程控制的,
STDIN => cat => WRITE\_END==READ\_END => wc => STDOUT
管道的基本原理和平常生活中的水管同樣,把東西從一個地方轉移到另一個地方。
還有一些要注意的,
讀會阻塞在空管道上,寫會阻塞在滿的管道上,這是由於讀空管道,沒有數據刻度,寫滿管道,沒有內存寫入空間,所以它們會等待數據的讀取或者等待內存的空閒,可使用O_NONBLOCK
標誌標識管道不會阻塞
import os import sys r, w = os.pipe() process_id = os.fork() if process_id: # Close write fd because parent not going to write os.close(w) r = os.fdopen(r) # Read from pipe msg = r.read() print "msg =", msg sys.exit(0) else: # This is the child process # Close read end cause child not going to read from pipe os.close(r) w = os.fdopen(w, 'w') # Write to pipe w.write("msg written by child...") w.close() sys.exit(0)