1. 程式人生 > >linux信號

linux信號

while sigalrm gprof error 信號處理 cti gin ini 接管

信號是由用戶、系統、進程發給目標進程的信息,以通知目標進程某個狀態的改變或者系統異常。linux信號產生條件為:

  • 在終端輸入字符,比如ctrl+z
  • 系統異常
  • 系統狀態變化。比如 alarm 定時器到期產生SIGALRM信號
  • 運行kill或者調用kill函數

查看Linux支持的信號命令:kill -l,可看到如下結果:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP 
6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1 
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM 
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP 
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ 
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR 
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3 
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8 
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7 
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2 
63) SIGRTMAX-1  64) SIGRTMAX

  給一個進程發送信號

使用 kill 函數:(man 2 kill)

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

int kill(pid_t pid, int sig);

  舉個栗子:

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

int main()
{
	pid_t pid = fork();

    if (pid > 0)
    {
        printf("in parent program..., child id: %d\n", pid);
        while (1){}
    }
    else if (pid == 0)
    {
        sleep(2);
        printf("in child program..., cur id: %d\n", getpid());
        pid_t ppid = getppid();
        printf("befor kill, ppid is %d\n", ppid);

        int ret = kill(ppid, SIGINT);
        printf("kill result is: %d, errno: %d\n", ret, errno);
        sleep(2);
        ppid = getppid();
        printf("after kill, ppid is %d\n", ppid);
    }

	return 0;
}

  運行結果為:

in parent program..., child id: 11519
in child program..., cur id: 11519
befor kill, ppid is 11518
kill result is: 0, errno: 0

sunny@hst:~/program/cpp$ after kill, ppid is 1

  在子進程,發送SIGINT(終端終端)信號給父進程,父進程退出。子進程被init進程接管,子進程的父進程號變為1

信號處理

使用signal函數捕獲信號

       #include <signal.h>

       typedef void (*sighandler_t)(int);

       sighandler_t signal(int signum, sighandler_t handler);

  定義sighandler_t類型的函數,該函數接受一個int類型的參數,這個參數指的是信號類型。信號函數應該是可重入的,嚴禁調用一些不安全的函數。

SIGKILL和SIGSTOP信號不能被捕獲或者忽略。

除了用戶自定義的信號處理函數外,x86_64-linux-gnu/bits/signum-generic.h 文件中,定義了三個其他處理方式:

#define SIG_ERR  ((__sighandler_t) -1)  /* Error return.  */
#define SIG_DFL  ((__sighandler_t)  0)  /* Default action.  */
#define SIG_IGN  ((__sighandler_t)  1)  /* Ignore signal.  */

  SIG_IGN 表示忽略信號,SIG_DFL表示使用信號的默認處理方式。

linux信號