Linux 信號詳解一(signal函數)


信號列表
SIGABRT        進程停止運行    6
SIGALRM        警告鍾    
SIGFPE        算述運算例外
SIGHUP        系統掛斷
SIGILL        非法指令
SIGINT        終端中斷   2
SIGKILL        停止進程(此信號不能被忽略或捕獲)
SIGPIPE        向沒有讀的管道寫入數據
SIGSEGV        無效內存段訪問
SIGQOUT        終端退出    3
SIGTERM        終止
SIGUSR1        用戶定義信號1
SIGUSR2        用戶定義信號2
SIGCHLD        子進程已經停止或退出
SIGCONT        如果被停止則繼續執行
SIGSTOP        停止執行
SIGTSTP        終端停止信號
SIGTOUT        后台進程請求進行寫操作
SIGTTIN        后台進程請求進行讀操作
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signal函數
    作用1:站在應用程序的角度,注冊一個信號處理函數
    作用2:忽略信號,設置信號默認處理 信號的安裝和回復
參數
--signal是一個帶signum和handler兩個參數的函數,准備捕捉或屏蔽的信號由參數signum給出,接收到指定信號時將要調用的函數有handler給出
--handler這個函數必須有一個int類型的參數(即接收到的信號代碼),它本身的類型是void
--handler也可以是下面兩個特殊值:① SIG_IGN 屏蔽該信號        ② SIG_DFL 恢復默認行為
//忽略,屏蔽信號
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <signal.h> int main(int arg, char *args[]) { pid_t pid=fork(); if(pid==-1) { printf("fork() failed! error message:%s\n",strerror(errno)); return -1; } //注冊信號,屏蔽SIGCHLD信號,子進程退出,將不會給父進程發送信號,因此也不會出現僵屍進程 signal(SIGCHLD,SIG_IGN); if(pid>0) { printf("father is runing !\n"); sleep(10); } if(pid==0) { printf("i am child!\n"); exit(0); } printf("game over!\n"); return 0; }

 

//恢復信號
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>

void catch_signal(int sign)
{
    switch (sign)
    {
    case SIGINT:
        printf("ctrl + C 被執行了!\n");
        //exit(0);
        break;
    }
}

int main(int arg, char *args[])
{
    //注冊終端中斷信號
    signal(SIGINT, catch_signal);
    char tempc = 0;
    while ((tempc = getchar()) != 'a')
    {
        printf("tempc=%d\n", tempc);
        //sleep()
    }
    //恢復信號
    signal(SIGINT, SIG_DFL);
    while (1)
    {
        pause();
    }
    printf("game over!\n");
    return 0;
}

 

//signal()函數的返回值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>

void catch_signal(int sign)
{
    switch (sign)
    {
    case SIGINT:
        printf("ctrl + C 被執行了!\n");
        //exit(0);
        break;
    }
}

int main(int arg, char *args[])
{
    /*
     * signal()函數的返回值是signal()函數上一次的行為
     * */
    typedef void (*sighandler_t)(int);
    //因為第一次注冊信號SIGINT,所以上一次的行為就是默認行為
    sighandler_t old=signal(SIGINT, catch_signal);
    if(old==SIG_ERR)
    {
        //注冊信號失敗
        perror("signal error");
    }
    /*正規寫法*/
    if(signal(SIGQUIT,catch_signal)==SIG_ERR)
    {
        //注冊新號失敗
        perror("signal error");
    }
    char tempc = 0;
    while ((tempc = getchar()) != 'a')
    {
        printf("tempc=%d\n", tempc);
        //sleep()
    }
    //把默認行為重新注冊,不就是恢復默認信號了
    signal(SIGINT, old);
    while (1)
    {
        pause();
    }
    printf("game over!\n");
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM