在多线程环境中的信号处理函数 [英] signal handler function in multithreaded environment

查看:555
本文介绍了在多线程环境中的信号处理函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的多线程GUI应用程序中我有以下的信号处理code。我想提高这个code,这样它会是正确的,线程安全的,但有一些事情,我不完全的信号处理的理解:


  • 是信号的进程或线程级处理(我能有具体的线程信号处理程序)?

  • 在该线程上下文是signal_handler函数执行?

  • 是可以在短时间内发送多个SIGTERM信号?

  • 它使SENS使用互斥的signal_handler?prevent并行执行


 无效signal_handler(INT SIG)
{
        开关(SIG)
        {
        案例SIGTERM:
            :: wxLogMessage(维先通(收到SIGTERM信号...));
            打破;
        案例SIGINT:
            :: wxLogMessage(维先通(收到SIGINT信号...));
            打破;
        案例SIGUSR1:
            :: wxLogMessage(维先通(收到SIGUSR1信号...));
            打破;
        默认:
            :: wxLogMessage(维先通(收到未知的信号...));
        }        //发送到wxCloseEvent主应用程序窗口
        :: wxGetApp()GetTopWindow() - 方式>关闭(真);
}

我注册的信号处理程序在我的初始化函数:

  //注册信号处理程序
信号(SIGTERM,signal_handler);
信号(SIGINT,signal_handler);
信号(SIGUSR1,signal_handler);


解决方案

要非常小心:作为的信号(7)页面告诉,只有极少数职能(异步信号安全的那些)可以(直接或间接调用内部信号处理)。互斥相关的功能可能不应该在信号处理函数被调用。另请参见的pthreads(7)

您可以考虑在你的信号设置挥发性sigatomic_t 变量处理程序,并且从时间测试标志的值时间。
如果你有C ++ 11(或C11)原子公司,例如C ++ 11 的std ::原子或C11的 < stdatomic.h> ,你可以作出这样的挥发性变量也是在这个意义上的原子。然后用原子负载设备进行测试。

Qt文档暗示以下窍门:创建一个<一个HREF =htt​​p://www.kernel.org/doc/man-pages/online/pages/man2/pipe.2.html相对=nofollow>管(2)自启动,然后让你的信号处理写(2)(即系统调用被指定为异步信号安全的)一个(或更多)字节[S]对管道的方法,以及有你GUI事件循环调查(2)该管道的读端。

A Linux的特定的方式来处理与Qt的信号可能是使用的 signalfd(2)可能与在QSocketNotifier (尽管名称,它适用于可轮询的文件描述符,不是的只有的插座)。与其他GUI工具包,你可能还可以添加一个文件描述符(一​​个从 signalfd 管道)被轮询

In my multithreaded GUI application I have following signal handling code. I want to improve this code so that it will be correct and threading safe but there are some things I don't fully understand in signal handling:

  • is signal handled at the process or thread level (can I have thread-specific signal handlers) ?
  • in which thread context is signal_handler function executed ?
  • is it possible to send many SIGTERM signals in a short time ?
  • does it make sens to use a mutex to prevent parallel execution of 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);
}

I register signal handlers in my init function:

// register signal handlers
signal(SIGTERM, signal_handler);
signal(SIGINT,  signal_handler);
signal(SIGUSR1, signal_handler);

解决方案

Be very careful: as the signal(7) page is telling, only very few functions (the "async-signal-safe" ones) can be (directly or indirectly) called inside signal handlers. Mutex related functions probably should not be called in signal handlers. See also pthreads(7)

You might consider setting a volatile sigatomic_t variable in your signal handler, and test the value of that flag from time to time. If you have C++11 (or C11) atomics, e.g. C++11 std::atomic or C11 <stdatomic.h>, you could make that volatile variable also atomic in that sense. Then use the atomic load facilities to test it.

The Qt documentation suggests the following trick: create a pipe(2) to self at startup, then have your signal handler write(2) (the write syscall is specified as being async-signal-safe) a single (or more) byte[s] to a pipe to your same process, and have your GUI event loop poll(2) the read end of that pipe.

A Linux-specific way to handle signals with Qt might be to use signalfd(2) probably with QSocketNotifier (despite the name, it works on pollable file descriptors, not only sockets). With other GUI toolkits, you probably can also add a file descriptor (the one from signalfd or pipe) to be polled.

这篇关于在多线程环境中的信号处理函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆