Linux信号的使用
1、信號的基本概念
信號是系統響應某個條件而產生的事件,進程接收到信號會執行相應的操作。與信號有關的系統調用在“signal.h”頭文件中有聲明。
常見信號的值,及對應的功能說明:
信號的值在系統源碼中的定義如下:
2.修改信號的響應方式– signal()
2.1修改SIGINT(即Ctral+C)信號響應方式
在鍵盤上按下 Ctrl+c 時,會給當前終端前臺執行的進程發送 SIGINT 信號,用 signal 修改 SIGINT 信號的響應方式示例代碼如下:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<signal.h>void fun(int sig) {sleep(5);printf("sig = %d\n",sig); }int main() {signal(SIGINT,fun);while(1){printf("hello\n");sleep(1);} }fun函數在這里不是我們調用的,我們以參數形式傳給signal,如果觸發信號,系統會調用fun函數,所以fun函數是一個回調函數。
signal一開始并不回調fun函數,當收到信號以后,程序會中斷,去處理信號問題,處理完信號問題以后,系統才會繼續執行。
執行結果:
程序運行時,我們執行Ctrl+C的時候,程序會回調fun函數 ,休眠五秒鐘,打印sig,處理完信號之后,然后再繼續執行的程序。
2.2將修改的信號響應方式修改為默認
那么如何將信號再次修改為原來的相應方式呢?將signal的第二個參數換成SIG_DFL即可我們用程序來展示:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include<signal.h>void fun(int sig) {sleep(3);printf("sig = %d\n",sig);signal(SIGINT,SIG_DFL);//將信號相應方式修改為默認 }int main() {signal(SIGINT,fun);while(1){printf("hello\n");sleep(1);} }運行結果:
第一次Ctral+C時系統回調fun函數,休眠5秒,輸出sig,將Ctral+C響應方式又修改為默認方式,所以第二次Ctral+C時,程序正常響應信號,中斷了程序的運行。
2.3忽略信號
忽略信號只需要將signal的第二個參數換成SIG_IGN即可我們用程序來展示:
代碼:
運行結果:
忽略了信號Ctral+C,所以Ctral+C沒有響應,程序不受影響。
3、發送信號 – kill()
kill() 可以向指定的進程發送指定的信號:
int kill(pid_t pid, int sig);
pid > 0 指定將信號發送個那個進程。
pid == 0 信號會被發送到和當前進程在同一個進程組的進程。
pid == -1 將信號發送給系統上有權限發送的所有的進程。
pid < -1 將信號發送給進程組 id 等于 pid 絕對值,并且有權限發送的所有的進程。
sig 指定發送信號的類型。
使用 kill()系統調用實現類似于系統 kill 命令的程序如下:
#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<unistd.h> #include<signal.h>//./main pid sig三個參數 int main(int argc,char* argv[]) {if(argc != 3){printf("arg error\n");exit(0);} int pid = 0;int sig = 0;sscanf(argv[1],"%d",&pid);sscanf(argv[2],"%d",&sig);if(kill(pid,sig) == -1){perror("kill error");}exit(0); }test.c為一個無限輸出hello的程序,運行test會不斷打印hello
當我們在另一個終端找到test的pid號,用我們自己寫的mykill對test發送信號。
然后發現test被中斷。(2信號是SIGINT信號,就是我們使用Ctral+C發送的信號)。
#define SIGKILL 9 //該信號的響應方式不允許改變
#define SIGTERM 15 //系統 kill 命令默認發送的信號
我們將2換成9或者15,就相當于對pid執行pkill強制結束或者kill結束。9號信號不允許修改響應方式,以應對所有進程。
總結
以上是生活随笔為你收集整理的Linux信号的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: exec进程替换
- 下一篇: 进程间通信(IPC机制)——管道