结合几个短小精悍的例子,学习Linux C信号的基本使用,给出程序运行方法和结果。

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

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR)
  printf("\ncan't catch SIGINT\n");
  // A long long wait so that we can easily issue a signal to this process
  while(1) 
    sleep(1);
  return 0;
}

运行方法和结果:

[root singal]#./singal &
[1] 23575

[root singal]#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
[root singal]#
[root singal]#kill -2 23575
received SIGINT
[root singal]#kill -2 23575
received SIGINT
[root singal]#kill -2 23575
received SIGINT
[root singal]#

信号的几种使用场景

常用信号
HUP 挂起信号 信号编号1
INT 中断信号 信号编号2
QUIT 退出信号 信号编号3 对应ctrl + c
KILL 杀死信号 信号编号9
SEGV 段错误信号 信号编号11
TERM 终止信号,kill命令默认发送的信号类型 信号编号 15
CONT 继续运行信号,恢复之前接受了STOP信号的进程
STOP 暂停信号 信号编号19

全部信号和对应的值可以使用kill -l
验证暂停和继续信号,可以使用如下例子
ping www.baidu.com > output.txt 2>&1 &
然后再开一个窗口,tail -f output.txt
然后通过kill -STOP/-CONT 进程号,观察tail的输出,验证进程暂停和恢复。

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

void sig_handler(int signo)
{
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGKILL)
        printf("received SIGKILL\n");
    else if (signo == SIGSTOP)
        printf("received SIGSTOP\n");
}

int main(void)
{
    if (signal(SIGUSR1, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGUSR1\n");
    if (signal(SIGKILL, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGKILL\n");
    if (signal(SIGSTOP, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGSTOP\n");
    // A long long wait so that we can easily issue a signal to this process
    while(1) 
        sleep(1);
    return 0;
}

运行方法和结果:

[root singal]#./singal &
[1] 24619
[root singal]#
can't catch SIGKILL

can't catch SIGSTOP

[root singal]#
[root singal]#
[root singal]#
[root singal]#kill -USR1 24619
received SIGUSR1
[root singal]#ls
singal  singal.c
[root singal]#jobs -l
[1]+ 24619 运行中               ./singal &
[root singal]#fg %1
./singal
received SIGUSR1
received SIGUSR1
received SIGUSR1
received SIGUSR1
received SIGUSR1

我们可以看到SIGKILL和SIGSTOP信号无法被捕获,运行时会有相应的错误信息输出。当我们向进程发送-USR1信号时,进程会输出received SIGUSR1