【问题标题】:Block signals for complete process in a multithreaded environment多线程环境中完整进程的阻塞信号
【发布时间】:2014-01-18 08:45:05
【问题描述】:

我在 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 变量(该信号处理程序正在修改)有多安全?

在我修改主线程或其他线程中的 sig_atomic_t 变量时不阻塞信号是否安全?

【问题讨论】:

  • 你能把代码贴在这里吗,方便指出
  • 使用 timer_create 而不是 setitimer。它允许你指定一个线程来传递信号。

标签: c linux pthreads signals posix


【解决方案1】:

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

man (7) signal

一个进程导向的信号可以被传递给当前没有阻塞信号的任何一个线程。如果多个线程的信号被解除阻塞,那么内核会选择一个任意线程来传递信号。

因为信号掩码是由每个线程从创建它们的任何线程继承的,一个相当标准的技术是在创建器中阻塞它们(为了简单起见,我们假设它是主线程),然后让每个派生线程在适当的时候解除阻塞信号。

对此的一个常见变体是在 main 中阻止它们,并在除一个之外的所有衍生线程中保持它们被阻止。一个线程解除对信号的阻塞,所有进程导向的信号都瞄准它来处理。

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

【讨论】:

  • 谢谢。尽管我也能够得出在主线程中禁用信号并控制来自所需线程的信号的结论。但我只是想知道人们是否使用其他方式来处理它。感谢您的确认。
  • 如果与您的建议接近,请同时参考添加的代码逻辑。
猜你喜欢
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 2012-10-08
  • 1970-01-01
相关资源
最近更新 更多