UNIX再学习 -- 发送信号
生活随笔
收集整理的這篇文章主要介紹了
UNIX再学习 -- 发送信号
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、發(fā)送信號的方式
發(fā)送信號的方式有幾種:
1、由鍵盤觸發(fā)的信號(只能發(fā)送一些比較特殊的信號)
SIGINT (2):ctrl+c ?中斷符
SIGQUIT (3):ctrl+\ ?退出符
SIGTSTP (20):ctrl+z ?停止符
2、由錯(cuò)誤和異常引發(fā)的信號
SIGILL (4) ? ?進(jìn)程試圖執(zhí)行非法指令
SIGBUS (7) ? ?硬件或?qū)R錯(cuò)誤
SIGFPE (8) ? ?算術(shù)異常
SIGSEGV (11) ? ?無法內(nèi)存訪問
SIGPIPE (13) ? ?向無讀取進(jìn)程的管道寫入
SIGSTKFLT (16) ? ?協(xié)處理器棧錯(cuò)誤
SIGXFSZ (25) ? ?文件資源超限
SIGPWR (30) ? ?斷電
SIGSYS (31) ? ?進(jìn)程試圖執(zhí)行無效系統(tǒng)調(diào)用
3、用專門的系統(tǒng)命令發(fā)送信號
kill [-信號] PIDs 若不指明具體的信號,缺省發(fā)送 SIGTERM (15) 信號。 該信號允許用戶優(yōu)雅地終止進(jìn)程。進(jìn)程可以選擇捕獲該信號,并在臨終之前完成必要的清理和善后工作。但如果捕獲了該信號,卻死賴著不走,則有流氓進(jìn)程之嫌。 若要指明具體信號,可以使用信號編號,也可以使用信號名稱,而且信號名稱中的“SIG”前綴可以省略不寫。例如: kill -9 1234 kill -SIGKILL 1234 kill -KILL 1234 kill -9 -1 (終止所有進(jìn)程)接收信號的進(jìn)程可以是一個(gè)、多個(gè)或所有的(PIDs 取 -1)。拆機(jī)用戶可以發(fā)送任何進(jìn)程,而普通用戶只能發(fā)送自己的進(jìn)程。二、發(fā)送信號的系統(tǒng)函數(shù)
1、函數(shù) kill
#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); 返回值:成功(至少發(fā)出去一個(gè)信號)返回 0,失敗返回 -1(1)函數(shù)功能
向指定進(jìn)程或進(jìn)程組發(fā)送信號(2)參數(shù)解析
kill 的 pid 參數(shù)有以下 4 種不同的情況。 pid > 0 ? ? 將該信號發(fā)送給進(jìn)程 ID 為 pid 的進(jìn)程 pid == 0 ?將該信號發(fā)送給與發(fā)送進(jìn)程屬于同一進(jìn)程組的所有進(jìn)程(這些進(jìn)程的進(jìn)程組 ID 等于發(fā)送進(jìn)程的進(jìn)程組 ID),而且發(fā)送進(jìn)程具有權(quán)限向這些進(jìn)程發(fā)送信號。這里用的術(shù)語“所有進(jìn)程”不包括實(shí)現(xiàn)定義的系統(tǒng)進(jìn)程集。對于大多數(shù) UNIX 系統(tǒng),系統(tǒng)進(jìn)程集包括內(nèi)核進(jìn)程和 init (pid 為 1)。 pid < 0 ? ? 將信號發(fā)送給其進(jìn)程組 ID 等于 pid 絕對值,而且發(fā)送進(jìn)程具有權(quán)限向其發(fā)送信號的所有進(jìn)程。如前所述,所有進(jìn)程并不包括系統(tǒng)進(jìn)程集中的進(jìn)程。 pid == -1 將該信號發(fā)送給發(fā)送進(jìn)程有權(quán)限向它們發(fā)送信號的所有進(jìn)程。若茜所述,所有進(jìn)程不包括系統(tǒng)進(jìn)程集中的進(jìn)程。? 參數(shù) sig 為信號編號,取 0 可用于檢查 pid 進(jìn)程是否存在,如果不存在 kill 函數(shù)返回 -1,且 errno 為 ESRCH。(3)示例說明
//示例一 //使用kill函數(shù)發(fā)送信號 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/types.h>void fa(int signo) {printf("捕獲到了信號%d\n",signo); }int main(void) {//使用fork函數(shù)創(chuàng)建子進(jìn)程pid_t pid = fork();if(-1 == pid){perror("fork"),exit(1);}if(0 == pid) //子進(jìn)程{printf("pid = %d\n",getpid());//設(shè)置對信號50進(jìn)行自定義處理signal(50,fa);while(1);}sleep(1);//判斷子進(jìn)程是否存在if(0 == kill(pid,0)){printf("父進(jìn)程發(fā)送信號50\n");kill(pid,50);}return 0; } 輸出結(jié)果: pid = 4569 父進(jìn)程發(fā)送信號50 捕獲到了信號50 //示例二 殺死進(jìn)程 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h>int main(void) {pid_t pid;if((pid=fork())<0){perror("fork");}else if(pid==0){printf("這是子進(jìn)程,pid=%d,",getpid());printf("父進(jìn)程的pid=%d\n",getppid());printf("按回車鍵,終止父進(jìn)程\n");getchar();kill(getppid(), SIGTERM);}else{printf("這是父進(jìn)程,pid=%d\n",getpid());while (1)pause();}return 0; } 輸出結(jié)果: 這是父進(jìn)程,pid=4705 這是子進(jìn)程,pid=4706,父進(jìn)程的pid=4705 按回車鍵,終止父進(jìn)程已終止(4)示例解析
示例一,發(fā)送信號 50 給子進(jìn)程。如果 kill 第二個(gè)參數(shù) sig 取 0,可判斷子進(jìn)程是否存在。 示例二,發(fā)送 SIGTERM 給指定父進(jìn)程。殺死特定進(jìn)程。2、函數(shù) raise
#include <signal.h> int raise(int sig); 返回值:成功返回 0,失敗返回非 0(1)函數(shù)功能
向調(diào)用進(jìn)程自己發(fā)送信號(2)參數(shù)解析
sig 為信號編號(3)函數(shù)解析
raise 函數(shù)實(shí)際上是給調(diào)用進(jìn)程或者線程發(fā)送信號。 對于單線程應(yīng)用來說,它相當(dāng)于 kill (getpid (), sig); 對于多線程應(yīng)用來說,它相當(dāng)于 pthread_kill (pthread_self (), sig); 若所發(fā)信號被捕獲,raise 函數(shù)會(huì)在信號處理函數(shù)返回后返回。(4)示例說明
//示例一 //使用raise函數(shù)發(fā)送信號 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h>void fa(int signo) {printf("捕獲到了信號%d\n",signo); }int main(void) {//設(shè)置信號2進(jìn)行自定義處理signal(2,fa);int res = sleep(10);if(0 == res){printf("總算美美地睡了個(gè)好覺\n");}else{printf("睡眠被打斷,還有%d秒沒有來得及睡\n",res);}//使用raise函數(shù)發(fā)送信號2raise(2);while(1);return 0; } 輸出結(jié)果: 總算美美地睡了個(gè)好覺 捕獲到了信號2 //示例二 進(jìn)程自殺 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h>int main (void) {printf ("按回車鍵,終止進(jìn)程\n");getchar ();raise (SIGTERM);while (1)pause ();return 0; } 輸出結(jié)果: 按回車鍵,終止進(jìn)程已終止(5)示例解析
示例一,如果不使用 ctrl+c,而是等待 10 秒,raise 函數(shù)會(huì)發(fā)送信號 2。 示例二,raise 發(fā)送信號 SIGTERM,終止進(jìn)程。總結(jié)
以上是生活随笔為你收集整理的UNIX再学习 -- 发送信号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UNIX再学习 -- 可重入函数和 SI
- 下一篇: JMS学习八(ActiveMQ消息持久化