Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理
好久没更新博客了,写篇文章除除草。这篇文章主要通过简单的例子说明一下Unix/Linux进程中如果捕捉和处理SIGTERM
、SIGUSR1
和SIGUSR2
信号。
先说明一下这三个信号:
信号(signal)是*nix系统中进程之间通信(IPC)的一种常见方式。
SIGTERM:进程终止信号,效果等同于*nix shell中不带-9的kill命令;
SIGUSR1:保留给用户使用的信号;
SIGUSR2:同SIGUSR1,保留给用户使用的信号。
1 信号的处理方式
对于SIGTERM
、SIGUSR1
和SIGUSR2
这三种信号,如果在当前进程中不进行捕获或者忽略(sighold)的话,*nix系统内核会自动使进程退出然后回收进程资源。那么进程如何优雅
地处理信号呢?通常需要根据实际情况处理:例如忽略,sigset( SIGCLD, SIG_IGN )
父进程忽略子进程退出信号,交由内核init进程回收处理;例如阻塞,sighold( SIGCLD )
暂时把子进程退出信号加入到信号掩码中,然后通过sigrelse( SIGCLD )
删除并重新接收该信号。
2 程序演示
下面通过两个程序简单演示一个进程如何对SIGTERM信号进行处理。
2.1 SIGTERM信号处理进程:sigterm.c
先为信号SIGTERM注册一个处理函数sTerminate,然后pause()
函数使当前进程一直处于挂起状态,直到接收到一个信号才返回。通过静态变量iExtFlag决定是否直接在SIGTERM信号处理函数sTerminate中使进程退出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
2.2 SIGTERM信号发送进程:sigkill.c
程序功能很简单:通过kill
函数把SIGTERM
信号发送给前面的sigterm进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
3 执行结果
使用GCC命令gcc -Wall sigterm.c -o sigterm
和gcc -Wall sigkill.c -o sigkill
编译生成可执行文件sigterm和sigkill。
然后输入./sigterm开启SIGTERM信号处理进程sigterm,界面在显示如下所示的当前进程PID后,由于pause
进入hung up状态。
Main process_pid=[27346] will sleep!
这时,在另一个shell终端上输入如下命令,sigkill进程向sigterm进程(27346)发送SIGTERM信号。
[root@typecodes signal]# ./sigkill 27346
##### 作用相当于直接通过Linux shell的kill命令:
[root@typecodes signal]# kill 27346
sigterm进程(27346)在接收到信号后,从pause函数中返回,并调用sTerminate函数进行处理。函数处理完后,继续执行pause函数后面的代码。于是,在sleep 10秒后,整个进程退出。
[root@typecodes signal]# ./sigterm
Main process_pid=[27346] will sleep!
Get a SIGTERM signal!
Main process begin to work!
Main process exit!
[root@typecodes signal]#
效果如图所示:
4 其它说明
对于通过执行./sigterm 1
使sigterm进程在接收到sigkill进程发送的信号后,这样sigterm进程就不会进入休眠状态而是直接在sTerminate函数中退出了。
由于进程对SIGUSR1
和SIGUSR2
等其它信号的处理方法和SIGTERM
可以完全一样,这里就不再演示了(只需要把两个程序中的SIGTERM替换即可)。
Comments »