我是靠谱客的博主 畅快航空,最近开发中收集的这篇文章主要介绍转-Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理

好久没更新博客了,写篇文章除除草。这篇文章主要通过简单的例子说明一下Unix/Linux进程中如果捕捉和处理SIGTERMSIGUSR1SIGUSR2信号。

先说明一下这三个信号:

信号(signal)是*nix系统中进程之间通信(IPC)的一种常见方式。
SIGTERM:进程终止信号,效果等同于*nix shell中不带-9的kill命令;
SIGUSR1:保留给用户使用的信号;
SIGUSR2:同SIGUSR1,保留给用户使用的信号。

1 信号的处理方式

对于SIGTERMSIGUSR1SIGUSR2这三种信号,如果在当前进程中不进行捕获或者忽略(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
/**
 * @FileName
sigterm.c
 * @Describe
Use kill function to send a signal to a process with the pid coming from argv[1]
 * @Author
vfhky 2015.08.03 https://typecodes.com/cseries/unixsigtermkill.html
 * @Excute
./sigterm means sTerminate() do not exit before;
./sigterm 1 means sTerminate() containing exit function.
 * @Return 0  */ #include <stdio.h> #include <stdlib.h> #include <signal.h> void sTerminate(); static int iExtFlag = 0; int main( int argc, char ** argv ) { sigset( SIGTERM, sTerminate ); printf( "Main process_pid=[%d] will sleep!n", getpid() ); if( argc == 2 && *argv[1] == 0x31 ) iExtFlag = 1; //the process will be hung up forever if not receving a signal. pause(); //if there is a signal coming, this code will keep going. printf( "Main process begin to work!n" ); //let the process being sleeping 10 sec, and exit then. sleep(10); printf( "Main process exit!n" ); return 0; } /**  * functions to handle the signal of SIGTERM.  * if the value of static variable iExtFlag is not equal zero, this func will exit without waiting for the main function to do to other things.  */ void sTerminate() { printf( "Get a SIGTERM signal!n" ); if( iExtFlag ) { printf( "Making process exit!n" ); exit(EXIT_SUCCESS); } return; } 
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
/**
 * @FileName
sigkill.c
 * @Describe
Use kill function to send a signal to a process with the pid from argv[1]
 * @Author
vfhky 2015.08.03 https://typecodes.com/cseries/unixsigtermkill.html
 * @Return
success:0
failure: -1
 */ #include <stdio.h> #include <stdlib.h> #include <signal.h> int main( int argc, char ** argv ) { if( argc != 2 ) { printf( "Usage: ./sigkill process_pid" ); return -1; } printf( "You will send a signal to the process=[%s]!n", argv[1] ); kill( atoi(argv[1]), SIGTERM ); printf( "Send over!n" ); return 0; } 

3 执行结果

使用GCC命令gcc -Wall sigterm.c -o sigtermgcc -Wall sigkill.c -o sigkill编译生成可执行文件sigterm和sigkill。 使用gcc编译程序

然后输入./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]#

效果如图所示:

sigterm进程的对sigterm信号的处理过程

4 其它说明

对于通过执行./sigterm 1使sigterm进程在接收到sigkill进程发送的信号后,这样sigterm进程就不会进入休眠状态而是直接在sTerminate函数中退出了。

由于进程对SIGUSR1SIGUSR2等其它信号的处理方法和SIGTERM可以完全一样,这里就不再演示了(只需要把两个程序中的SIGTERM替换即可)。

转载于:https://www.cnblogs.com/sunyongjie1984/p/5835795.html

最后

以上就是畅快航空为你收集整理的转-Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理的全部内容,希望文章能够帮你解决转-Unix系统进程对SIGTERM、SIGUSR1和SIGUSR2信号处理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部