二 Linux進程間通信( 二 )

代碼示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {int i = 1;while(1){printf("do working %d\n",i);//給自己發送一個信號if(i == 4){//自己給自己發送編號為15的信號raise(SIGTERM);}i ++;sleep(1);}return 0; }運行結果如下:

二 Linux進程間通信

文章插圖
(3)abort函數
#include<stdlib.h>void abort(void);功能:給自己發送異常終止信號6)SIGABRT,并且產生core文件,等價于kill(getpid(),SIGABRT);參數:無返回值:無代碼示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {int i = 1;while(1){printf("do working %d\n",i);//給自己發送一個信號if(i == 4){//給自己發送一個編號為6的信號,默認的行為就是終止進程abort();}i ++;sleep(1);}return 0; }運行結果如下:
二 Linux進程間通信

文章插圖
通過軟件條件產生在上一篇博客介紹過,管道如果讀端不讀了 , 存儲系統會發生SIGPIPE 信號給寫端進程 , 終止進程 。這個信號就是由一種軟件條件產生的,這里再介紹一種由軟件條件產生的信號SIGALRM(時鐘信號) 。
#include<unistd.h>unsigned int alarm(unsigned int seconds);功能:設置定時器(鬧鐘) 。在指定seconds后,內核會給當前進程發送14)SIGALRM信號,進程收到該信號,默認動作終止 。每個進程都有且只有唯一的一個定時器 。取消定時器alarm(0),返回舊鬧鐘余下秒數 。參數:seconds:指定的時間,以秒為單位返回值:返回0或剩余的秒數
  • 定時,與進程狀態無關(自然定時)就緒、運行、掛起(阻塞 , 暫停)、終止、僵尸.......無論進程處于何種狀態,alarm都計時 。
代碼示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {unsigned int ret = 0;//第一次設置鬧鐘5秒之后就超時 發送對應的信號ret = alarm(5);printf("上一次鬧鐘剩下的時間是%u\n",ret);sleep(2);//之前沒有超時的鬧鐘被新的鬧鐘給覆蓋ret = alarm(4);printf("上一次鬧鐘剩下的時間是%u\n",ret);printf("按下任意鍵繼續...");getchar();return 0; }運行結果:
二 Linux進程間通信

文章插圖
通過硬件異常產生硬件異常被硬件以某種方式被硬件檢測到并通知內核,然后內核向當前進程發送適當的信號 。這里給大家介紹兩個硬件異常:CPU產生異常 和 MMU產生異常
CPU產生異常 發生除零錯誤,CPU運行單元會產生異常,內核將這個異常解釋為信號,最后OS發送SIGFPE信號給進程 。
代碼示例:
#include <stdio.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>int main(){// 由軟件條件產生信號alarm函數和SIGPIPE// CPU運算單元產生異常 , 內核將這個異常處理為SIGFPE信號發送給進程int a = 10;int b = 0;printf("%d", a/b);return 0;}運行結果小伙伴們自己下去運行一下吧~這里就不截圖了
MMU產生異常: 當進程訪問非法地址時,mmu想通過頁表映射來將虛擬轉換為物理地址 , 此時發現頁表中不存在該虛擬地址,此時會產生異常,然后OS將異常解釋為SIGSEGV信號,然后發送給進程
#include <stdio.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>int main(){// MMU硬件產生異常 , 內核將這個異常處理為SIGSEGV信號發送給進程signal(11, handler);int* p = NULL;printf("%d\n", *p);return 0;}signal函數實現信號的捕捉#include<signal.h>typedef void(*sighandler_t)(int);//它定義了一個類型sighandler_t,表示指向返回值為void型(參數為int型)的函數(的)指針sighandler_t signal(int signum , sighandler_t handler);功能:注冊信號處理函數(不可用于SIGKILL、SIGSTOP信號),即確定收到信號后處理函數的入口地址 。此函數不會阻塞 。參數:signum:信號的編號 , 這里可以填數字編號,也可以填信號的宏義 。handler:取值有3種情況:SIG_IGN:忽略該信號SIG_DFL:執行系統默認動作信號處理函數名:自定義信號處理函數,如:func回調函數的定義如下:void func(int signo){//signo為觸發的信號 , 為signal()第一個參數的值}返回值:成功:第一次返回NULL,下一次返回此信號上一次注冊的信號處理函數的地址 。如果需要使用此返回值,必須在前面先聲明此函數指針的類型 。失?。悍祷豐IG_ERR

推薦閱讀