內核中幾個用於信號產生的函數:
specific_send_sig_info():向進程發送信號
group_send_sig_info():向進程組發送信號
send_signal(): 將信號插入掛起信號隊列
specific_send_sig_info()
向t發送信號sig
參數
- sig
信號ID
- info
信號的附加信息
- t
進程描述符
其中,參數info
可能的取值如下:
值 | 意義 |
---|---|
(siginfo_t) | info是指向siginfo_t結構的指針 |
0 | 信號由用戶發送 |
1 | 信號由內核發送 |
2 | 信號由內核發送,且信號是:SIGSTOP或SIGKILL |
複雜性
t阻塞這個信號
t被跟蹤
sig是實時信號
sig已經掛起在t的pending列表上
sig必須插入到t的pending列表上,並且這個過程可能失敗
內核需要通知t有新的掛起信號
TIF_SIGPENDING需要被置位
進程狀態是TASK_INTERRUPTIBLE或TASK_STOPPED的時候,需要喚醒進程
t正在另一個處理器上運行
send_signal()
向指定進程的掛起隊列中插入新元素
參數
- sig
信號ID
- info
附加信息
- t
進程描述符
- signals
掛起信號隊列的地址
複雜性
sig是實時信號;
sig是SIGKILL或SIGSTOP,這兩個信號不能被阻塞,忽略和捕捉(APUE);
t->user->sigpending大於t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
分配新的sigqueue結構失敗;
爲用戶簿記資源;
設置隊列位掩碼中與信號相關的位
;
將sig插入到t的掛起信號隊列以後,順手阻塞sig,這是普通信號的特徵,我可以理解.但是,sigaddset(&signals->signal, sig);
這行代碼疑點太多:
1.signals是什麼類型的數據結構?爲什麼signals->signal會指示一個sigset_t域?signals->signal是掛起信號隊列的阻塞信號掩碼,如pending.signal和shared_pending.signal;而進程描述符的blocked是做什麼用的呢?我知道用處之一是作爲do_signal()的oldset參數的替補.
2.爲什麼這行代碼要在第7步和第10步執行兩次?
group_send_sig_info()
向p所在的線程組發送信號sig
參數
- sig
- info
- p
進程描述符的地址
複雜性
sig是一個錯誤的值
這個函數可由用戶進程調用或接受來自用戶進程的參數用戶進程越權發出此信號
sig=0
目標進程可能正被殺死
爲什麼正在被殺死的進程要做特殊處理?sig可能使p線程組中的其他掛起信號無效
之前的函數爲什麼不檢查這一點?p忽略sig
sig已有一個掛起的實例
向共享掛起信號隊列中添加sig
從p中喚醒一個進程處理sig