天天看點

信号的基本操作 kill 函數 父程序給子程序發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程序接收到信号後的處理方式信号的基本操作

信号的基本操作

     kill 函數

#include <sys/types.h>
#include <signal.h>

/*
 * 功能:
 *  給指定程序發送信号
 * 參數:
 *   pid:
 *     pid > 0:
 *       将信号傳送給程序 ID 為 pid 的程序
 *     pid = 0:
 *       将信号傳送給目前程序所在程序組中的所有程序
 *     pid = -1:
 *       将信号傳送給系統内所有的程序
 *     pid < -1:
 *       将信号傳給指定程序組的所有程序。 這個程序組号等于 pid 的絕對值
 *   signum:信号的編号
 * return:
 *  成功:0
 *  失敗:-1
 * 
 */
int kill(pid_t pid, int signum)
           

 父程序給子程序發送信号

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        perror("fork");
    }

    if(0 == pid)
    {
        int i = 0;
        for(i = 0; i < 5;i++)
        {
            printf("in son process\n");
            sleep(1);
        }
    }
    else
    {
        printf("in father process\n");
        sleep(2);
        printf("kill sub process now\n");
        kill(pid, SIGINT);
    }

    return 0;
}
           

       列印:

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

    alarm 函數

#include <unistd.h>

/*
 *功能:
 *  在 seconds 秒後,向調用程序發送一個 SIGALRM 信号
 *  SIGALRM 信号的預設動作:終止調用 alarm 函數的程序
 * return:
 *   若以前沒有設定過定時器,或設定的定時器已逾時,傳回 0
 *   否則傳回定時器剩餘的秒數,并重新設定定時器
 */
unsigned int alarm(unsigned int seconds)
           

 例子:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int seconds = 0;

    seconds = alarm(5);    
    printf("seconds = %d\n",seconds);

    sleep(2);

    seconds = alarm(5);
    printf("seconds = %d\n",seconds);

    while(1);

    return 0;
}
           

列印:

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

    raise 函數

#include <signal.h>

/*
 * 功能:
 *  給調用程序本身送一個信号
 * 參數:
 *   signum: 信号的編号
 * return:
 *   成功: 0
 *   失敗: -1
 */
int raise(int signum);
           

   例子:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    printf("in raise function\n");

    sleep(2);
    raise(SIGALRM);

    sleep(10);

    return 0;
}
           

列印:

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

    abort 函數

#include <stdlib.h>

/*
 * 功能:
 *  向程序發送一個 SIGABRT 信号, 預設情況下程序會退出
 * 注意:
 *  即使 SIGABRT 信号被加入阻塞集,一旦程序調用了 abort 函數,程序也還是會被終止,且在終止前會重新整理緩沖區,關檔案描述符
 */
void abord(void);
           

   pause 函數

#include <unistd.h>

/*
 * 功能:
 *   将調用程序挂起直至捕捉到信号為止
 *   這個函數通常用于判斷信号是否已到
 * return:
 *   直到捕獲到信号,pause 函數才傳回-1,且 errno 被設定成 EINTR
 */
int pause(void)
           
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("in pause function\n");

    pause();

    return 0;
}
           

列印:

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

    程序接收到信号後的處理方式

          執行系統預設動作

         忽略此信号

         執行自定義信号處理函數

              程式中可用函數 signal()改變信号的處理方式

#include <signal.h>

/*
 * 功能:
 *  注冊信号處理函數(不可用于 SIGKILL、SIGSTOP 信号),即确定收到信号後處理函數的入口位址
 * 參數:
 *   signum:信号編号
 *   handler:
 *      忽略該信号: SIG_IGN
 *      執行系統預設動作: SIG_DFL
 *      自定義信号處理函數: 信号處理函數名
 * return:
 *    成功:傳回函數位址,該位址為此信号上一次注冊的信号處理函數的位址
 *    失敗:傳回 SIG_ERR
 */
typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);
           

注冊信号處理函數

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void signal_handler(int signo);

int main()
{
    printf("wait for SIGINT OR SIGQUIT\n");

    signal(SIGINT, signal_handler);
    signal(SIGQUIT, signal_handler);

    pause();
    pause();

    return 0;
}
void signal_handler(int signo)
{
    if(signo == SIGINT)
    {
        printf("recv SIGINT\n");
    }

    if(signo == SIGQUIT)
    {
        printf("recv SIGQUIT\n");
    }
}
           

列印:

   操作:ctrl+\    ctrl+c   ctrl + z

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

驗證 signal 函數的傳回值

#include <stdio.h>
#include <signal.h>
#inlcude <unistd.h>

typedef void (*sighandler_t)(int);

void fun1(int signo);
void fun2(int signo);

int main(int argc, char *argv[])
{
    sighandler_t previous = NULL;

    previous = signal(SIGINT, fun1);
    if(previous == NULL)
    {
        printf("return fun addr is NULL\n");
    }

    previous = signal(SIGINT, fun2);
    if(previous == fun1)
    {
        printf("return fun addr is fun1\n");
    }

    previous = signal(SIGQUIT,fun1);
    if(previous == NULL)
    {
        printf("return fun addr is NULL\n");
    }
    return 0;
}

void fun1(int signo)
{
    printf("in fun1\n");
}

void fun2(int signo)
{
    printf("in fun2\n");
}
           

       列印:

信号的基本操作 kill 函數 父程式給子程式發送信号 驗證 signal 函數的傳回值 alarm 函數 raise 函數 abort 函數 pause 函數 程式接收到信号後的處理方式信号的基本操作

繼續閱讀