前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个sigprocmask和sigsuspend函数的综合应用

一个sigprocmask和sigsuspend函数的综合应用

作者头像
typecodes
发布2024-03-29 14:33:43
720
发布2024-03-29 14:33:43
举报
文章被收录于专栏:typecodestypecodes

在Linux服务端后台开发中,经常会用到信号处理函数:sigprocmasksigsuspend。这篇文章主要通过一个综合实例演示如何使用sigprocmask函数屏蔽目标信号(信号掩码)以及sigsuspend函数挂起进程。

Linux中编译执行sigprocmask_sigsuspend程序
Linux中编译执行sigprocmask_sigsuspend程序
1 sigprocmask和sigsuspend函数的说明

关于sigprocmask函数的说明:

代码语言:javascript
复制
头文件:    #include <signal.h>
函数:     int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
功能:     用于获取或者改变当前进程的信号掩码(当前进程屏蔽的信号集)。
返回值:    0成功,-1失败(具体原因由errno值表示)。

关于sigsuspend函数的说明:

代码语言:javascript
复制
头文件:    #include <signal.h>
函数:     int sigsuspend(const sigset_t *mask);
功能:     阻塞当前进程(TASK_INTERRUPTIBLE可中断状态),等待mask信号集(信号掩码)之外的任何信号的到来。
            在收到pendmask之外)信号后,先调用该信号的处理函数,然后把信号集mask还原为原来的信号集,接着从sigsuspend调用处返回(进程恢复执行)。
返回值:    该系统调用始终返回-1,并将errno设置为EINTR。
2 完整的程序实例

在CentOS服务器中使用编译并执行下面这段程序,效果如上图所示。

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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

/** * @FileName sigprocmask_sigsuspend.c * @Describe A simple example for using sigprocmask and sigsuspend functions in linux. * @Author vfhky 2016-02-29 11:21 https://typecodes.com/cseries/sigprocmasksigsuspendapp.html * @Compile gcc sigprocmask_sigsuspend.c -o sigprocmask_sigsuspend */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #include <errno.h> //Signal handle function. void sig_handler( int signal ) { printf( "Receive signal=%d.\n", signal ); return; } int main( int argc, char *argv[] ) { printf( "getpid=%d.\n", getpid() ); int i = 0; //Register a signal. struct sigaction new_act; sigemptyset( &new_act.sa_mask ); new_act.sa_handler = sig_handler; new_act.sa_flags = 0; sigaction( SIGUSR1, &new_act, 0 ); sigaction( SIGUSR2, &new_act, 0 ); sigaction( SIGINT, &new_act, 0 ); //Add SIGINT, SIGUSR1/SIGUSR2 signals to the signal-set of new_set. sigset_t new_set, old_set; sigemptyset( &new_set ); sigaddset( &new_set, SIGINT ); //2 sigaddset( &new_set, SIGUSR1 ); //10 //sigaddset( &new_set, SIGUSR2 ); //12 /** * Repalce the old mask set with the new mask set.Thus the process will block the signal of SIGINT and SIGUSR1, * but it will excute the function of sig_handler when the signal such as SIGUSR2 other than SIGINT, SIGUSR1 arrives. */ sigprocmask( SIG_SETMASK, &new_set, &old_set ); //Add SIGUSR1 and SIGUSR2 signals to the signal-set of pendmask. sigset_t pendmask; sigemptyset( &pendmask ); sigaddset( &pendmask, SIGUSR1 ); //10 sigaddset( &pendmask, SIGUSR2 ); //12 //Replaces the signal mask of the process with pendmask temporarily and suspends the process until delivery of a signal whose action is to invoke a signal handler or to terminate a process. i = sigsuspend( &pendmask ); printf( "Sigsuspend returned with value%d.\n", i ); if( errno == EINTR ) { printf( "%dInterrupted by a signal.\n", errno ); } while(1) { printf( "--while.\n" ); sleep(3); } return 0; }

3 发送SIGUSR1和SIGUSR2信号

如下图所示,使用kill命令向进程(PID:7154)发送SIGUSR1SIGUSR2信号。

发送SIGUSR1和SIGUSR2信号
发送SIGUSR1和SIGUSR2信号

由于sigsuspend函数把信号SIGUSR1SIGUSR2加入到信号掩码pendmask中,所以这两个信号的到来对当前进程没有任何影响。

4 发送SIGINT信号

使用命令kill -SIGINT 7154向当前进程(PID:7154)发送SIGINT信号。由于该信号不在信号掩码pendmask中,所以先调用SIGINT信号的处理函数sig_handler,然后把现在的信号集pendmask还原为原来的new_set信号集。

这时,由于之前由于信号掩码pendmask被屏蔽的未决信号信号SIGUSR1SIGUSR2由内核重新传递,所以进程会执行SIGUSR2信号的处理函数(SIGUSR1信号被信号集new_set所屏蔽,因此不会执行)。接着进程从sigsuspend调用处返回,恢复执行(进入while循环)。

执行SIGINT和SIGUSR2信号处理函数
执行SIGINT和SIGUSR2信号处理函数

如果继续发送SIGINT信号,因为被加入到了当前信号掩码new_set中,所以也会被屏蔽(对进程无影响)。最后可以通过命令kill -SIGKILL 7154将整个进程关闭。

继续发送SIGINT和SIGKILL信号
继续发送SIGINT和SIGKILL信号
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-02-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 sigprocmask和sigsuspend函数的说明
  • 2 完整的程序实例
  • 3 发送SIGUSR1和SIGUSR2信号
  • 4 发送SIGINT信号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档