今日学习linux技术总结

本文详细介绍了Linux进程如何使用sigprocmask函数设置信号屏蔽字,包括不同操作方式SIG_BLOCK、SIG_SETMASK和SIG_UNBLOCK的应用,以及如何通过示例代码演示信号集操作。理解信号屏蔽在信号处理中的作用,有助于更有效地管理进程信号行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux 进程信号屏蔽字 - 设置进程信号屏蔽字

用 sigaction 函数处理信号时,可以一并设置进程的信号屏蔽字。但是有单独的函数可以用来设置进程的信号屏蔽字:sigprocmask 函数。
sigprocmask 函数
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
1
2
参数 how 的取值如下:

名称    说明
SIG_BLOCK    把参数 set 中的信号添加到信号屏蔽字中
SIG_SETMASK    把信号屏蔽字设置为参数 set 中的信号
SIG_UNBLOCK    从信号屏蔽字中删除参数 set 中的信号
信号集操作函数
#include <signal.h>
int sigemptyset(sigset_t *set);                // 初始化信号集为空
int sigaddset(sigset_t *set, int signo);    // 向信号集中添加信号
int sigfillset(sigset_t *set);                // 初始化信号集为包含所有已定义的信号
int sigdelset(sigset_t *set, int signo);    // 删除给定的信号

int sigismember(sigset_t *set, int signo);  // 判断给定信号是否一个信号集的成员。返回值 1:是,0:不是,-1:信号无效

将信号加入进程屏蔽字,进程将屏蔽该信号,不做响应!!!(而在 sigaction 信号处理函数中,屏蔽的信号会被排队,并在随后被处理)
代码如下:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void handleSig(int);

void main(){
    signal(SIGINT, handleSig);
    signal(SIGALRM, handleSig);

    int res;
    sigset_t set;
    sigset_t oset;
    sigemptyset(&set);
    sigemptyset(&oset);
    sigaddset(&set, SIGINT);    // 添加 SIGINT 信号到信号集
    sigaddset(&set, SIGALRM);

    res = sigprocmask(SIG_SETMASK, &set, &oset); // 设置进程信号屏蔽字为 set 信号集

    while(1){
        printf("alive.\n");
        sleep(2);
    }
}

void handleSig(int sig){
    switch(sig){
        case SIGINT:
            //
            printf("got sigint\n");
            sleep(10);
            printf("got sigint. done.\n");
            break;
        case SIGALRM:
            //
            printf("got sigalrm\n");
            sleep(10);
            printf("got sigalrm. done.\n");
            break;
    }
}

sigprocmask函数总结sigprocmask

一个进程的信号屏蔽字规定了当前阻塞而给该进程的信号集。调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作。

#include <signal.h>
int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset );
返回值:若成功则返回0,若出错则返回-1
首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回。

其次,若set是一个非空指针,则参数how指示如何修改当前信号屏蔽字。

表10-4说明了how可选用的值。注意,不能阻塞SIGKILL和SIGSTOP信号。

表10-4 用sigprocmask更改当前信号屏蔽字的方法

  how

  说明

  SIG_BLOCK      该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集。set包含了我们希望阻塞的附加信号
  SIG_UNBLOCK      该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集补集的交集。set包含了我希望解除阻塞的信号
  SIG_SETMASK      该进程新的信号屏蔽字将被set指向的信号集的值代替
 

如果set是空指针,则不改变该进程的信号屏蔽字,how的值也无意义。


在调用sigprocmask后如果有任何未决的、不再阻塞的信号,则在sigprocmask返回前,至少会将其中一个信号递送给该进程。
我们知道, 当造成信号的事件发生,比如硬件异常(如除以0),软件条件(如alarm计时器超时)、终端产生的信号或调用kill函数产生的信号,内核向进程发送一个信号。当我们连续多次产生同一个信号,比如SIGINT信号, 系统究竟是只接受第一个而屏蔽了以后多个信号呢?还是都接收信号?我们当且敢肯定的是第一个信号是会被接收(在sigprocmask中没有屏蔽这个信号)的。此时,调用进程会转到信号处理程序中, 因为我们可以用sigprocmask来检测当前进程的信号屏蔽字的,所以我们就可以在信号处理程序中来查看此信号是否被屏蔽了。
所以我们来看一段代码,代码意思就是检测SIGINT信号, 当发生信号后转到sig_int(int) 函数中, 在pr_mask函数中,使用了sigprocmask函数来检测当前进程是否屏蔽了SIGINT信号:

linux信号的阻塞和未决linux信号的阻塞和未决

LINUX C中sigprocmask()函数用法

C语言sigaction()函数:查询或设置信号处理方式

会话setsid的作用

linux c——dup( )和dup2( )函数详解

Linux进程间通信详解(六) 信号种类及函数

C语言alarm()函数:设置信号传送闹钟

C语言fcntl()函数:文件描述词操作函数

Linux系统编程——特殊进程之僵尸进程

linux进程利用SIGCHLD信号,来实现父进程回收子进程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值