首先,signal函数和sigprocmask函数都是用于处理进程屏蔽信号的函数,而pthread_sigmask函数则是用于处理线程屏蔽信号的函数。它们的区别在于作用对象不同。
signal函数可以设置信号的处理方式,可以将信号忽略、捕捉或者使用默认处理方式。但是需要注意的是,signal函数只能处理一些基本的信号,例如SIGINT、SIGTERM等,不能处理实时信号。
sigprocmask函数可以设置进程屏蔽信号的集合,可以屏蔽某些信号的处理,使得在这些信号未被解除屏蔽之前,进程不会收到这些信号。但是需要注意的是,sigprocmask函数只能屏蔽信号的接收,不能处理信号。
pthread_sigmask函数与sigprocmask函数类似,可以设置线程屏蔽信号的集合。但是需要注意的是,pthread_sigmask函数只能屏蔽信号的接收,不能处理信号。
针对实时信号无法被处理的问题,可能是由于实时信号的优先级较高,导致其他信号被阻塞无法处理。可以使用sigaction函数替代signal函数来处理实时信号,并使用sigprocmask或pthread_sigmask函数屏蔽其他信号的接收,以避免信号被阻塞。
以下是一个使用sigaction函数处理实时信号的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void handler(int signo)
{
printf("receive signal %d\n", signo);
}
int main()
{
struct sigaction act, oldact;
// 设置信号处理函数
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
// 注册实时信号处理函数
if(sigaction(SIGRTMIN, &act, &oldact) < 0)
{
perror("sigaction error");
exit(1);
}
// 屏蔽其他信号的接收
sigset_t newmask, oldmask;
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
sigaddset(&newmask, SIGTERM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
while(1)
{
sleep(1);
}
return 0;
}
signal() 函数是最早的一种方法,但是它有一些缺陷,比如在多线程环境下使用时会出现问题。sigprocmask() 和 pthread_sigmask() 函数则是更加通用的方法,可以在多线程环境下使用。这两个函数的区别在于前者是进程级别的,后者是线程级别的。
关于为什么选用后两种方法测试程序(实时信号)却没有生效,线程没有处理,主进程收到实时信号反而异常直接退出了,可能是因为实时信号的优先级比较高,而且处理时间也比较短,如果不及时处理就会出现问题。另外,如果使用了多线程,那么需要注意线程之间的同步问题。