信號

信號允許進程終端其他進程把沼,他通知進程系統(tǒng)中發(fā)生了一種某種類型的事件详民,又稱為軟件中斷。

信號傳遞的步驟
  1. 發(fā)送信號涛酗,內(nèi)核通過更新進程上下文中的某個狀態(tài)铡原,發(fā)送一個信號給目的進程。發(fā)送信號有2個原因:1)內(nèi)核檢測到一個事件商叹,比如除零錯誤(SIGFPE)或子進程終止燕刻;2)一個進程調(diào)用了kill函數(shù),顯示地要求內(nèi)核發(fā)送一個信號給目的進程剖笙。一個進程可以發(fā)送信號給自己卵洗。
  2. 接收信號,當目的進程收到內(nèi)核發(fā)送的信號弥咪,進程可以忽略該信號、終止或者通過執(zhí)行一個信號處理程序的用戶層函數(shù)捕獲該信號聚至。
常見的信號:
SIGINT

程序終止信號酷勺,用戶鍵入INTR字符(通常是Ctrl-C)時發(fā)出,用于通知前臺進程組終止進程扳躬。默認終止進程鸥印,不可捕獲、阻塞或忽略坦报。

SIGQUIT

與SIGINT類似库说,但由QUIT字符(通常是Ctrl-\)來控制,進程在因收到SIGQUIT退出時會產(chǎn)生core文件片择,在這個意義上類似于一個程序錯誤信號潜的。默認終止進程,不可捕獲字管、阻塞或忽略啰挪。

SIGKILL

用來立即結束程序的運行信不,本信號不能被阻塞、處理或忽略亡呵。如果管理員發(fā)現(xiàn)某個進程終止不了抽活,可嘗試發(fā)送這個信號。
默認導致進程退出锰什,不可忽略或捕捉下硕。

SIGUSER1/SIGUSER2

留給用戶使用,默認終止汁胆,可捕獲梭姓、阻塞或忽略

SIGALARM

時鐘定時信號,計算的是實際的時間或時鐘時間嫩码,alarm函數(shù)使用該信號誉尖。默認終止進程,可捕獲铸题、阻塞或忽略

SIGCHLD

子進程結束時铡恕,父進程會收到這個信號。丢间,如果父進程沒有處理這個信號探熔,也沒有等待子進程,子進程雖然終止千劈,但是還是會在內(nèi)核進程表中占有該信號,這是進程變?yōu)榻┦M程牌捷,應盡量避免墙牌。默認忽略,可捕獲暗甥、阻塞或忽略

信號的發(fā)送

1. 從鍵盤發(fā)送

Ctrl+Z:發(fā)送SIGTSTP信號
Ctrl+C:發(fā)送SIGINT信號

2. 通過kill函數(shù)

進程可以通過調(diào)用kill函數(shù)發(fā)送信號給其他進程(包括他自己)

#python3.6
#os.kill(pid, sig)
import signal
import os
import functools
import time

def main():
    pid = os.fork()
    if pid > 0: #parent process
        _print = functools.partial(print, 'parent:')
        _print("I'm parent process!")
        time.sleep(5)
        _print("Notify SIGKILL to my child!")
        os.kill(pid, signal.SIGKILL)
        
    elif pid == 0: #child process
        _print = functools.partial(print, 'child:')
        _print("I'm child process!")
        
        cnt = 1
        while True:
            _print(cnt, "time")
            time.sleep(1)
            cnt += 1
            
            
if __name__ == "__main__":
    main()
    
"""result:
parent: I'm parent process!
child: I'm child process!
child: 1 time
child: 2 time
child: 3 time
child: 4 time
child: 5 time
child: 6 time
parent: Notify SIGKILL to my child!
"""
3. 用alarm函數(shù)發(fā)送信號

進程可以調(diào)用alarm函數(shù)給自己發(fā)送SIGALARM信號喜滨,使用SIGALARM信號可以實現(xiàn)一些定時任務。

#python3.6
import signal
import functools
import datetime

def handle_alarm(sig, frame):
    print(datetime.datetime.now(), "alarm")
    signal.alarm(5)

def main():
    signal.signal(signal.SIGALRM, handle_alarm)
    signal.alarm(5)
    
    cnt = 0
    while True:
        pass
        
if __name__ == "__main__":
    main()
    
"""result:
2018-03-25 13:42:22.380555 alarm
2018-03-25 13:42:27.382360 alarm
2018-03-25 13:42:32.385036 alarm
...
"""
接收信號

當內(nèi)核從一個議程處理程序返回撤防,準備將控制傳遞給進程時虽风,會檢查進程違背阻塞的待處理信號的集合,如果這個集合為空寄月,呢么內(nèi)核將控制傳遞給進程的下一個指令辜膝。如果這個集合為非空,那么內(nèi)核會選擇集合中某個信號(通常是最小的k)漾肮,并且強制進程接收信號厂抖,收到這個信號會觸發(fā)進程的某個行為。一旦完成這個行為克懊,那么默認就默認傳遞回進程邏輯控制流的下一個指令忱辅。

每一個信號都有一個預定義的默認行為七蜘,如下:

  1. 進程終止;
  2. 進程終止并轉向存儲器墙懂;
  3. 進程停止直到SIGCONT信號重啟橡卤;
  4. 進程忽略該信號;

進程可以通過signal來修改和信號相關的默認行為损搬。但SIGSTOP和SIGKILL的默認行為不可更改碧库。

#C
signal(signum, handler)
handler == SIG_IGN:忽略設置的信號
hanldler == SIG_DFL:將信號行為恢復為默認行為
handler == callable:當進程收到該信號就會調(diào)用改函數(shù)
``

```python
#python3.6
import signal
import functools
import datetime

def handle_sigint(sig, frame):
    print("receive signal",sig)
    exit(0)

def main():
    signal.signal(signal.SIGINT, handle_sigint) #修改Ctrl+c的處理方式
    signal.pause() # 進程休眠直到收到信號
        
if __name__ == "__main__":
    main()
    
"""result:
^Creceive signal 2
"""
顯示阻塞和取消阻塞信號

有時候不希望再接收到信號后立即去處理,但也不希望忽略改信號场躯,而是延時一段時間再去處理谈为,就可以通過阻塞信號來實現(xiàn)。當解除阻塞后踢关,被阻塞的信號將會被傳遞到進程伞鲫。

信號阻塞和信號忽略是不同的,內(nèi)核在信號阻塞被解除之前不會傳遞出去签舞,信號只是本暫停傳遞秕脓;但信號忽略不同,信號已經(jīng)被傳遞給進程儒搭,只是進程沒有處理吠架,并將其丟棄。

#include<signal.h>
int sigpromask(int how, const sigset_t * set, sigset_t * oldset)
import signal
import time

def handle_sigint(sig, frame):
    print("receive signal",sig)
    exit(0)

def main():
    sig_pend = signal.sigpending()
    sig_pend.add(signal.SIGINT) 
    print("mask singal:", signal.SIGINT)
    signal.pthread_sigmask(signal.SIG_BLOCK, sig_pend)
    signal.signal(signal.SIGINT, handle_sigint)
    cnt = 0
    while cnt < 10:
        print(cnt," time")
        time.sleep(1)
        cnt += 1
    print("unmask singal:", signal.SIGINT)
    
    signal.pthread_sigmask(signal.SIG_UNBLOCK, set([signal.SIGINT]))
        
if __name__ == "__main__":
    main()
    
"""result:
mask singal: Signals.SIGINT
0  time
1  time
^C2  time       #Ctrl+c
3  time
4  time
5  time
6  time
7  time
8  time
9  time
unmask singal: Signals.SIGINT
receive signal 2
"""
參考
  1. 《深入理解計算機系統(tǒng)》
待補充
  1. 信號的狀態(tài):阻塞信號和未決信號
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搂鲫,一起剝皮案震驚了整個濱河市傍药,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌魂仍,老刑警劉巖拐辽,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異擦酌,居然都是意外死亡俱诸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門赊舶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睁搭,“玉大人,你說我怎么就攤上這事笼平≡奥妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵寓调,是天一觀的道長遇伞。 經(jīng)常有香客問我,道長捶牢,這世上最難降的妖魔是什么鸠珠? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任巍耗,我火速辦了婚禮,結果婚禮上渐排,老公的妹妹穿的比我還像新娘炬太。我一直安慰自己,他們只是感情好驯耻,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布亲族。 她就那樣靜靜地躺著,像睡著了一般可缚。 火紅的嫁衣襯著肌膚如雪霎迫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天帘靡,我揣著相機與錄音知给,去河邊找鬼。 笑死描姚,一個胖子當著我的面吹牛涩赢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轩勘,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筒扒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绊寻?” 一聲冷哼從身側響起花墩,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澄步,沒想到半個月后冰蘑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡驮俗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年懂缕,在試婚紗的時候發(fā)現(xiàn)自己被綠了允跑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片王凑。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖聋丝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤啦逆,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布臀玄,位于F島的核電站,受9級特大地震影響况木,放射性物質發(fā)生泄漏垒拢。R本人自食惡果不足惜旬迹,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望求类。 院中可真熱鬧奔垦,春花似錦、人聲如沸尸疆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寿弱。三九已至犯眠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間症革,已是汗流浹背筐咧。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留地沮,地道東北人嗜浮。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像摩疑,于是被迫代替她去往敵國和親危融。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容