阻止信号在多线程环境中完成整个过程

时间:2013-12-31 11:49:23

标签: c linux pthreads signals posix

我在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变量时,不安全地阻止信号会安全吗?

1 个答案:

答案 0 :(得分:2)

您的问题是各种信号可以指向整个过程或特定线程。当针对整个过程时,它们将被传递给任何没有被阻止的线程。

man (7) signal

  

可以将过程引导的信号传递给当前没有阻塞信号的任何一个线程。如果多个线程的信号未被阻塞,则内核会选择一个任意线程来传递信号。

因为信号掩码是由创建它们的任何线程的每个线程继承的,所以一种相当标准的技术是在创建者中阻塞它们(为简单起见,假设这是主要的),然后让每个衍生线程在适当时解除阻塞信号。

这方面的一个常见变体是在main中阻止它们,并在除了一个之外的所有衍生线程中阻止它们。一个线程解锁信号,所有过程定向信号都瞄准它处理。

以上可能是你想要做的。您可能正在阻止运行信号处理程序的线程中的SIGALRM。不幸的是,这不会阻止SIGALRM被传递到第二个线程。