信号处理程序在多线程环境中的功能

signal handler function in multithreaded environment

本文关键字:功能 环境 多线程 程序 信号处理      更新时间:2023-10-16

在我的多线程GUI应用程序中,我具有以下信号处理代码。我想改进此代码,以使其正确且线程安全,但是在信号处理中我不完全理解某些事情:

  • 是在过程或线程级别上处理信号(我可以有特定于线程的信号处理程序)吗?
  • 在哪个线程上下文中执行了哪个线程上下文?
  • 是否可以在短时间内发送许多Sigterm信号?
  • 使用Mutex防止并行执行Signal_handler是有意义的吗?

void signal_handler(int sig)
{
        switch (sig)
        {
        case SIGTERM:
            ::wxLogMessage(wxT("SIGTERM signal received ..."));
            break;
        case SIGINT:
            ::wxLogMessage(wxT("SIGINT signal received ..."));
            break;
        case SIGUSR1:
            ::wxLogMessage(wxT("SIGUSR1 signal received ..."));
            break;
        default:
            ::wxLogMessage(wxT("Unknown signal received ..."));
        }
        // send wxCloseEvent to main application window
        ::wxGetApp().GetTopWindow()->Close(true);
}

我在我的初始功能中注册信号处理程序:

// register signal handlers
signal(SIGTERM, signal_handler);
signal(SIGINT,  signal_handler);
signal(SIGUSR1, signal_handler);
  • 信号处理程序是每个程序状态 - 也就是说,一个过程中的所有线程共享相同的安装信号处理程序功能。
  • 信号掩码是每个线程状态。信号可以按每线程阻止或未阻止。
  • 信号可以是过程或线程指导的。如果信号是过程定向的,则选择当前没有信号类型的任意线程被选择来处理。

在多线程应用程序中处理信号的一种简单方法是创建一个线程作为专用的信号处理线程。每个线程中所有感兴趣的信号都被阻止;没有建立信号处理程序;信号处理线程在循环中调用sigwaitinfo(),在收到的信号上作用。

这意味着您不必担心要调用的功能是否为 async-signal-safe ,因为信号没有在信号处理程序中处理 - 它们是由您的专用信号处理线程同步处理,可以调用它喜欢的任何功能(例如,它可以使用普通的Pthreads同步函数唤醒另一个线程)。

要非常小心:正如信号(7)页面所讲的那样,只有很少的函数(" async-signal-safe" ,请参见信号 - 安全性(7)可以(直接或间接)被称为内部信号处理程序。与MUTEX相关的功能可能不应在信号处理程序中调用。另请参见Pthreads(7)

您可以考虑在信号处理程序中设置挥发性Sigatomic_t变量,并不时测试该标志的值。如果您有C 11(或C11)原子,例如C 11 STD :: Atomic或C11 <stdatomic.h>,您可以使该volatile变量也可以从这个意义上进行。然后使用原子负载设施对其进行测试。

QT文档提出了以下技巧:在启动时创建一个管道(2),然后让您的信号处理程序写入(2)(write syscall指定为异步 - 信号安全))字节[s]到您相同过程的管道,并进行GUI事件循环民意调查(2)该管道的读取端。

a linux特异性使用QT处理信号的方法可能是使用signalfd(2)可能与qsocketNotifier一起使用(尽管有名称,但它可用于可引导的文件描述符,而不是插座)。使用其他GUI工具包,您可能还可以添加要进行轮询的文件描述符(来自signalfdpipe的文件)。

此答案是指posix threads( pthreads)。

引用1:

可以在线程级别上处理信号,是的。如果一个过程的多个线程处理一个信号,并且将信号ist发送到该过程,但是对于特定的线程,则无法确定哪个线程的处理程序将处理信号。(有关详细信息,请参见man pthread_kill()

引用2:

信号处理程序将在设置它的线程的上下文中归咎于。这包括主线程。

引用3:

如果将同一类型的多种信号发送到同一过程,则在离开信号队列之前,它们可能仅将其凝结成一个信号。我必须承认,这是否可以区分我不确定的线程级别。

引用4:

如果共享资源涉及游戏:是的,至少对于处理程序代码的部分,同时访问这些资源。此外,这也取决于您尝试实现的逻辑。