被阻塞的信号能否将进程从semop信号量等待队列唤醒?
问题解答
核心结论
被阻塞的信号确实可以唤醒处于semop这类可中断系统调用等待状态的进程。
原理说明
- 当进程陷入如
semop、pause、read(无O_NONBLOCK标记)这类可中断的系统调用等待时,内核在收到任何信号(无论是否被阻塞)时都会唤醒该进程。 - 若信号被阻塞,进程被唤醒后不会执行对应的信号处理函数,而是让原本的系统调用返回错误码
EINTR(表示调用被信号中断),进程可据此判断是否需要重新发起系统调用。 - 仅
SIGKILL、SIGSTOP这类不可阻塞/忽略的信号,会直接触发进程终止或停止,而非仅唤醒。
代码示例分析
你的代码展示了信号阻塞的基本逻辑,以下是带中文注释的版本:
#include <stdio.h> #include <signal.h> #include <unistd.h> #include <string.h> sigset_t all_signals; void sigusr1_handler(int signo) { printf("收到SIGUSR1信号\n"); // 初始化包含所有信号的信号集 sigfillset(&all_signals); // 设置进程信号掩码,阻塞所有信号 sigprocmask(SIG_SETMASK, &all_signals, NULL); } int main() { struct sigaction sa; bzero(&sa, sizeof(sa)); sa.sa_handler = sigusr1_handler; sa.sa_flags = 0; // 注册SIGUSR1的信号处理函数 sigaction(SIGUSR1, &sa, NULL); // 第一次发送SIGUSR1,触发处理函数,之后阻塞所有信号 raise(SIGUSR1); // 第二次发送SIGUSR1,此时信号已被阻塞,会进入挂起状态 raise(SIGUSR1); return 0; }
如果这段代码在调用semop等待信号量时收到被阻塞的信号,semop会立即返回EINTR,进程从等待状态被唤醒,但不会执行信号处理函数。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

