Linux Signals 进程信号简介
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
在Linux中,signal是一種局限較強(qiáng)的進(jìn)程間通信方式。
主要有三種類型:
1. 從hardware signal到POSIX signal
????hardware signal也叫hardware interrupt,CPU中存放著 interrupt vectors 指向 存放在kernel space中的interrupt handling routine。
? ? 例: 鍵盤輸入;segmentation fault -> SIGSEGV?
2. 直接從kernel生成的POSIX signal
? ? 例:exit() -> SIGCHLD
3. 從一個(gè)進(jìn)程發(fā)起到另一個(gè)進(jìn)程的signal
? ? 例:進(jìn)程885 執(zhí)行了 “kill 1234” 代碼
?
POSIX signal
1.?Generated from CPU to kernel, or from CPU to processes
????例 1: Segmentation fault.
????????The signal is labeled SIGSEGV, which comes from CPU to kernel then to process.
????例 2: Floating point exception (e.g., divided by 0).
????????The signal is labeled SIGFPE, which is coming from CPU to process
2. From kernel to process
????例: Child process termination.
????????The signal is labeled SIGCHLD, which is coming from the kernel to process
3.?Generated from one process to another
? ? 例:?From terminals: E.g., “Ctrl C”, “Ctrl Z”
????????????Using programs: E.g., “kill”, “top”, etc.
????????????Using the “kill()” system call.
?
一些典型的signal
?
Asynchronous signal: 異步信號(hào)
– The signal received is NOT generated by the process itself。?So, its arrival time is usually not deterministic
– E.g., External hardware interrupt, another process sends ctrl-c
Synchronous signal: 同步信號(hào)
– The signal is caused by the process itself, its arrival time is usually deterministic
– E.g., A certain line leads to SIGFPE?
– E.g., A certain line accesses a memory region: SIGSEGV
?
kill() 方法
用于給特地進(jìn)程發(fā)送POSIX signal
?
signal() 方法
更新當(dāng)前進(jìn)程的特定signal的處理方法,即signal handler
例:寫個(gè)無法“Ctrl+C”中止的小病毒
#include <stdio.h> #include <signal.h>void sig_handler(int sig) {if(sig == SIGINT)printf("\nCtrl + C\n"); }int main(void) {signal(SIGINT, sig_handler);printf("Press enter\n");getchar();printf("End of program\n");return 0; }?
通常情況下,我們希望當(dāng)signal handler處理完signal后,程序恢復(fù)到之前執(zhí)行的地方;而有時(shí)候,則希望程序繼續(xù)運(yùn)行下去。
?
signal的檢查方法
一個(gè)進(jìn)程如何知道它收到了一個(gè)特定的signal?
在kernel space中,有一個(gè)bitmask
進(jìn)程會(huì)不定期地去檢查這個(gè)bitmask,如果看到是1,則調(diào)用對(duì)應(yīng)的handler,并重置為0。
因此,發(fā)送signal和處理signal是異步的。
?
pause()方法
The pause() system call suspends the calling process until a signal is received. 等待一個(gè)信號(hào)
?
有益的重寫signal handler
重寫SIGINT的handler,保證進(jìn)程在被用戶ctrl-c 中止之前,進(jìn)行一些必要的清理工作比如 關(guān)閉數(shù)據(jù)庫連接等。
?
alarm()方法
設(shè)置一個(gè)“鬧鐘”在指定時(shí)間后“響”起。
通過在hardware設(shè)置一個(gè)鬧鐘,到達(dá)時(shí)間后,hardware的signal會(huì)轉(zhuǎn)換成SIGALRM signal發(fā)送給進(jìn)程,默認(rèn)的處理方式是結(jié)束當(dāng)前進(jìn)程。
alarm()是一次性的,如果需要周期性的,則使用 settimer()方法
?
?
轉(zhuǎn)載于:https://my.oschina.net/Bruce370/blog/885260
總結(jié)
以上是生活随笔為你收集整理的Linux Signals 进程信号简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP安装加载yaf扩展
- 下一篇: Linux最佳聊天软件:Skype 4.