我在linux中有一个'C'应用程序,我在其中注册了SIGALRM处理程序。我的SIGALRM处理程序更新了其他线程也在访问的一些全局数据。 需求: 为了保护全局数据,我需要在线程内部访问时完全阻塞信号。所以我需要一种方法来实现它。 问题: 我无法完全阻止信号。 sigprocmask不起作用。虽然如果main是唯一运行的线程,它会阻止信号。但是当多个线程运行时,SIGALRM会继续运行。 我已经测试了pthread_sigmask,但只更新了当前线程的信号掩码。
添加代码逻辑:
sig_atomic_t atm_var;
void signal_handler()
{
atm_var++;
}
void thread_func()
{
pthread_sigmask(UNBLOCK,...);
while(1)
{
/* some stuff */
pthread_sigmask(BLOCK,...);
/* critical section, can easily access or modify atm_var */
pthread_sigmask(UNBLOCK,...);
}
}
int main()
{
sigprocmask(BLOCK,...);
pthread_create(...,thread_func,...);
sigaction(SIGALRM,...);
setitimer(ITIMER_REAL,...);
while(1)
{
}
}
再补充一点:在主线程或其他线程中修改sig_atomic_t变量(信号处理程序正在修改)的安全性如何?
OR
在我修改主线程或其他线程中的sig_atomic_t变量时,不安全地阻止信号会安全吗?
答案 0 :(得分:2)
您的问题是各种信号可以指向整个过程或特定线程。当针对整个过程时,它们将被传递给任何没有被阻止的线程。
man (7) signal
可以将过程引导的信号传递给当前没有阻塞信号的任何一个线程。如果多个线程的信号未被阻塞,则内核会选择一个任意线程来传递信号。
因为信号掩码是由创建它们的任何线程的每个线程继承的,所以一种相当标准的技术是在创建者中阻塞它们(为简单起见,假设这是主要的),然后让每个衍生线程在适当时解除阻塞信号。
这方面的一个常见变体是在main中阻止它们,并在除了一个之外的所有衍生线程中阻止它们。一个线程解锁信号,所有过程定向信号都瞄准它处理。
以上可能是你想要做的。您可能正在阻止运行信号处理程序的线程中的SIGALRM。不幸的是,这不会阻止SIGALRM被传递到第二个线程。