首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我在sigaction之前执行sigemptyset,但有时SIGALRM被阻塞

在使用信号处理函数时,我们通常会在调用sigaction函数之前调用sigemptyset函数来清空信号集,以确保信号处理函数不会被其他信号中断。然而,有时候我们会发现即使在调用sigemptyset之后,仍然会出现SIGALRM信号被阻塞的情况。

这是因为在多线程程序中,每个线程都有自己的信号屏蔽字(signal mask),用于指定哪些信号在当前线程中被阻塞。当一个线程调用sigemptyset函数时,只会清空该线程的信号屏蔽字,而不会影响其他线程的信号屏蔽字。

如果在调用sigemptyset之后,另一个线程调用了sigprocmask函数来修改信号屏蔽字,可能会导致SIGALRM信号被阻塞。因此,即使在主线程中调用了sigemptyset,在其他线程中仍然可能出现SIGALRM信号被阻塞的情况。

为了解决这个问题,我们可以在每个线程中都调用sigemptyset函数来清空信号屏蔽字,或者使用pthread_sigmask函数来设置线程的信号屏蔽字。这样可以确保在每个线程中都清空了SIGALRM信号的阻塞状态,从而避免出现信号被阻塞的情况。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

linux系统中socket错误码:EINTR和EAGAIN的处理

目录 人为重启中断的系统调用 安装信号时设置 SA_RESTART属性 忽略信号 ---- 永远阻塞的系统调用,信号中断,导致其不继续等待,转而去执行signal_handler 1、什么是慢系统调用...2、EINTR错误产生的原因-(阻塞的系统调用、或者非阻塞的系统调用) 如果进程一个慢系统调用(slow system call)中阻塞时,当捕获到某个信号且相应信号处理函数返回时,这个系统调用不再阻塞而是中断...sigemptyset(&action.sa_mask); sigaction(SIGALRM, &action, NULL); EAGAIN-(一般用于非阻塞的系统调用) 非阻塞的系统调用...; 注意,并不是所有的系统调用都可以自动恢复。...有时我们需要捕获信号,但又考虑到第②种方法的局限性(设置 SA_RESTART属性对有的系统无效,如msgrcv),所以在编写代码时,一定要“人为重启中断的系统调用”。

6.3K10
  • 引入信号后的几种陷阱讲解

    这是 alarm 是由硬件在即时的,它不会因为CPU其他程序抢占而暂停即时,而是继续即时,当其他程序占用 CPU 时间片时,alarm 超时发送了信号,可当前程序还处于挂起状态,内核只记录了程序接下来该去执行信号捕获处理函数...如果我们执行 alarm 函数之前调用一个信号阻塞函数,把 SIGALRM 信号给阻塞掉,然后 pause 之前阻塞的信号解除,这样如果 CPU 其他程序抢占,再回到程序时,pause 能成功接收到...其实与上面的场景也是一样的,因为解除信号屏蔽和 pause 之前一样是存在间隙的,如果在这个间隙中 CPU 抢占,pause 一样也是无法得到 SIGALRM 信号的。...(SIGALRM, &act, &oldact); // 阻塞 SIGALRM 信号 sigset_t block, oldset, suspend; sigemptyset(&block); sigaddset.../ 获取原来的信号阻塞集列表 suspend = oldset; // 将 SIGALRM 信号解除 sigdelset(&suspend, SIGALRM); /* * 该函数执行了三个操作 *

    20330

    Linux信号种类与函数

    SIGQUIT:与SIGINT类似,由Ctrl+\(QUIT字符)控制,进程收到该信号时会产生core文件,类似于一个程序错误信号。 SIGLL:执行了非法指令,通常是可执行文件本身错误。...SIGSTOP:停止(stopped)进程的执行,注意和terminate及interrupt的区别,该进程还未结束,只是暂停执行,该信号与SIGKILL一样不能阻塞、处理或忽略。...即使SIGABORT进程设置为阻塞信号,调用abort后,SIGABORT仍能进程接收。...信号的阻塞 Linux的信号控制中,有时不希望进程接收到信号时立刻中断进行的执行,也不希望该信号完全忽略,而是延时一段时间再去调用相关的信号处理函数。...信号掩码是由阻塞的发送给当前进程的信号组成的信号集。

    3K30

    linux系统编程之信号(六):竞态条件与sigsuspend函数

    4. nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程。 5. 从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是sig_alrm。 6....切换到用户态执行sig_alrm函数,进入sig_alrm函数时SIGALRM信号自动屏蔽,从sig_alrm函数返回时SIGALRM信号自动解除屏蔽。...需要注意的是虽然sig_alrm函数什么都没干,还是得注册作为SIGALRM的处理函数,因为SIGALRM信号的默认处理是终止进程,这也是mysleep函数返回时要恢复SIGALRM信号原来的sigaction...此外,mysleep函数的返回值表示“未睡到”的时间,即unslept,当尚未计时到nsecs而pause函数先其他信号处理函数所中断返回,在外界看来就是sleep期间其他信号处理函数中断了,则mysleep...我们可能会想到,调用pause之前屏蔽SIGALRM信号使它不能提前递达就可以了。看看以下方法可行吗? 1. 屏蔽SIGALRM信号; 2. alarm(nsecs); 3.

    1.6K00

    信号

    信号状态: 产生 递达:信号被捕捉并处理 未决:信号阻塞 信号四要素: 编号、事件、名称、默认处理动作 7.2 进程处理信号行为 1、默认动作 2、忽略 3、捕捉 (后面两种处理行为就需要涉及到信号集了...别急 7.4 阻塞信号集 阻塞信号集也叫做当前进程的信号屏蔽字。 这里的屏蔽应该理解为阻塞而非忽略 (1)sigprocmask 调用sigprocmask函数可以读取或更改进程的信号屏蔽字。...=catch_sig; //清空信号集 sigemptyset(&act.sa_mask); sigaction(SIGALRM, &act, NULL); //setitimer 5秒之后每隔...sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); //signum 要捕捉的信号 //handler 要执行的捕捉函数指针...act; act.sa_flags=0; sigemptyset(&act.sa_mask); act.sa_handler=catch_sig; sigaction(SIGCHLD,

    1.2K20

    Linux系统-进程信号

    /C++当中除零,内存越界等异常,系统层面上,是当成信号处理的 三、阻塞信号 1、信号其他相关常见概念 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生到递达之间的状态...,称为信号未决(Pending) 进程可以选择阻塞 (Block )某个信号 阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 注:阻塞和忽略是不同的,...,直到信号递达才清除该标志 在上图,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作;SIGINT信号产生过,正在被阻塞,所以暂时不能递达。...sigset_ t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态 初始化sigset_t变量之后就可以调用sigaddset和sigdelset...中断或者系统调用处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达 内核决定返回用户态后执行sighandler函数,sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和调用的关系

    3.5K10

    异步通信之 信号

    如果我们把2号信号设置成阻塞(即在阻塞信号集的对应位置设为1),那么来一个2号信号,则未信号集的对应值置为1,什么时候阻塞信号集中的对应位置变成0了,什么时候未决信号集才能去处理之前阻塞的那个信号。...SIGCONT 让一个停止(stopped)的进程继续执行. 本信号不能阻塞. 可以用一个handler来让程序由stopped状态变为继续执行时完成特定的工作....本信号不能阻塞, 处理或忽略. SIGTSTP 停止进程的运行, 该信号可以处理和忽略....类似于SIGALRM, 但是计算的是该进程占用的CPU时间. SIGPROF 类似于SIGALRM/SIGVTALRM, 包括该进程用的CPU时间以及系统调用的时间....是退出,4.3BSD中是忽略;SIGCONT进程挂起时是继续,否则是忽略,不能阻塞

    1.2K20

    进程信号大总结(整理)

    总结思考一下 上面所说的所有信号产生,最终都要有OS来进行执行为什么?OS是进程的管理者 信号的处理是否是立即处理的?合适的时候 信号如果不是立即处理,那么信号是否需要暂时进程记录下来?...阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作. 注意,阻塞和忽略是不同的,只要信号阻塞就不会递达,而忽略是递达之后可选的一种处理动作。 2....SIGINT信号产生过,正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前 不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。...注意,使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的 状态。...阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作. 注意,阻塞和忽略是不同的,只要信号阻塞就不会递达,而忽略是递达之后可选的一种处理动作。

    10010

    Linux内核编程--进程通信信号

    2) 未决状态:信号产生和递送之间的时间间隔内,称信号是未决的(pending) 如果为进程产生了一个该进程设置为阻塞的信号,而且对该信号的动作是默认或者捕捉该信号,则内核为该进程将此信号保持为未决状态...内核递送一个原来阻塞的信号给进程时(而不是产生信号时),才决定对他的处理方式。所以,进程信号递送给他之前仍可以改变该信号的处理动作。...信号阻塞集用来描述哪些信号递送到该进程的时候阻塞信号发生时记住它,直到进程准备好时再将信号通知进程) 3) 递送状态:产生的信号通知给进程,信号处理 六,信号的种类: 类型信号值范围说明不可靠信号信号值...sigaction实时信号 实时信号都支持排队,都是可靠信号非实时信号 非实时信号都不支持排队,都不是可靠信号 七,进程对信号的处理: 进程执行信号相应处理函数之前,首先要把信号进程中注销。...如果SIGABRT注册了一个捕获函数,那么执行abort()还会导致进程终止吗?

    2.9K20

    Linux进程信号总结

    实际上当前的云服务器一秒内可以执行的累加次数远大于两万,那为什么上述代码运行结果比实际结果要小呢?...阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。 需要注意的是,阻塞和忽略是不同的,只要信号阻塞就不会递达,而忽略是递达之后的一种处理动作。...在上图中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作 SIGINT信号产生过,正在被阻塞,所以暂时不能递达。...阻塞信号集中“有效”和“无效”的含义是该信号是否阻塞未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。...sigismember函数:判断set所指向的信号集中是否包含某种信号,若包含则返回1,不包含则返回0,调用失败返回-1 注意: 使用sigset_t类型的变量之前,一定要调用sigemptyset

    6210

    信号的概念及基本操作

    ---- 而并非只有杀死进程用到了信号,linux/unix中,很多场景都用到了信号机制,在说这些场景之前,我们先来看一下系统一共有多少个信号,终端下使用命令 kill -l 可以查看所有信号和信号编号...本信号不能忽略,处理和阻塞。 SIGUSE1 Term 用户定义的信号,即程序员可以程序中定义并使用该信号。...pipe向一个没有读端的管道写数据 SIGALRM Term 定时器超时,超时的时间 由系统调用alarm设置 SIGTERM Term 程序结束信号,与SIGKILL不同的是,该信号可以阻塞和终止...,不能忽略,处理和阻塞 SIGSTOP Stop 提供给管理员暂停进程的特权,不能忽略,处理和阻塞 SIGTSTP Stop 停止进程的运行。...当sig等于0时,将不发送信号,依然执行错误检查。

    21010

    Linux进程信号(产生、保存、处理)可重入函数概念volatile理解SIGCHLD信号

    后续将代码拿出while循环,只执行一次除0操作,结果依旧如下。  通过上面的测试,有以下两个问题: ①为什么执行一次除0操作跟不断执行除0操作的结果是一样的?...即执行了一次除0操作,为什么进程不断处理SIGFPE信号? ②操作系统怎么知道除0了? 这一块就跟硬件有关系了。接下来,我们通过硬件来分析除0操作。...解决了上面的第二个问题,再来看看第一个问题,为什么执行一次除0操作,信号却一直自定义处理。...进程可以选择阻塞 (Block )某个信号。 阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。...当我们进入main函数,进入insert方法对链表进行节点头插,执行到head=p,即将新节点的地址交给头节点的这一步之前,因为硬件中断使进程切换到内核,再次回用户态之前检查到有信号待处理,于是切换

    1.4K10

    L007Linux信号、信号处理和信号处理函数

    本信号不能忽略、处理和阻塞。默认动作为终止进程。它向系统管理员提供了一种可以杀死任何进程的方法。 (10) SIGUSR1:用户定义的信号,即程序可以程序中定义并使用该信号。默认动作为终止进程。...(15) SIGTERM:程序结束(terminate)信号,与SIGKILL不同的是,该信号可以阻塞和处理。通常用来要求程序正常退出。执行Shell命令kill时,缺少产生这个信号。...本信号不能忽略、处理和阻塞。默认作为暂停进程。 (19) SIGTSTP:停止进程的动作,该信号可以处理和忽略。按下组合键时发出该信号。默认动作为暂停进程。...如果在进程解除对某个信号的阻塞之前,这种信号发生了多次,那么如果信号递送多次(即信号未决信号队列里面排队),则称之为可靠信号;只递送一次的信号称为不可靠信号。...第二个参数是指向结构sigaction的一个实例的指针,结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理;第三个参数oldact指向的对象用来保存原来对相应信号的处理

    4.1K30

    【Linux】信号>信号产生&&信号处理&&信号保存&&信号详解

    (Pending) 进程可以选择阻塞 (Block )某个信号 阻塞的信号产生时将保持未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 阻塞和忽略是不同的,只要信号阻塞就不会递达,而忽略是递达之后可选的一种处理动作...在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作 SIGINT信号产生过,正在被阻塞,所以暂时不能递达。...sigset_ t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。...当前正在执行main函数,这时发生中断或异常切换到内核态。中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。...系统默认的忽略动作和用户用sigaction函数自定义的忽略通常是没有区别的,这是一个特例。

    15810
    领券