读取信号处理程序内的共享数据

时间:2011-12-13 16:00:40

标签: c linux mutex signals signal-handling

我处于这样一种情况,我需要在信号处理程序( SIGSEGV 信号处理程序)中读取二进制搜索树(BST),根据我的知识,它是每个线程基础。 BST可以由应用程序中的其他线程修改。

现在由于信号处理程序无法使用信号量,互斥量等因此无法访问共享数据,如何解决此问题?请注意,我的应用程序是多线程的,并在多核系统上运行。

4 个答案:

答案 0 :(得分:4)

您不应该从信号处理程序访问共享数据。您可以在以下文章中找到有关信号的更多信息:

Linux Signals for the Application Programmer

The Linux Signals Handling Model

All about Linux signals

到目前为止,看起来在linux中处理信号最安全的方法是signalfd。

答案 1 :(得分:4)

我可以看到两个非常干净的解决方案:

  1. 特定于Linux:创建专用线程处理信号。使用signalfd()捕获信号。这样您就可以在常规线程中处理信号,而不是任何有限的处理程序。
  2. Portable:也可以使用专用线程,直到收到信号为止。您可以使用管道创建一对文件描述符。线程可以从第一个描述符读取(2),在信号处理程序中,您可以将(2)写入第二个描述符。根据{{​​3}},在信号处理程序中使用write()是合法的。当线程从管道读取内容时,它知道它必须执行某些操作。

答案 2 :(得分:3)

假设SH无法直接访问共享数据,那么也许你可以间接地进行访问:

  1. 有一些全局变量,只有信号处理程序可以写入,但可以从其他地方读取(即使只在同一个线程内)。
  2. SH在调用时设置标志
  3. 线程在不修改BST的过程中轮询此标志;当找到它时,它们执行原始信号所需的处理(使用任何必要的同步),然后引发不同的信号(如SIGUSR1)以指示处理已完成
  4. THAT信号的SH重置标志
  5. 如果您担心重叠SIGSEGV,请在混音中添加一个计数器以跟踪。 (嘿!你刚刚建立了自己的信号量!)

    这里的薄弱环节显然是民意调查,但它是一个开始。

答案 3 :(得分:1)

您可以考虑mmap - fuse文件系统(在用户空间中)。

实际上,你会对Gnu Hurd支持external pagers

感到高兴

也许你在信号处理程序中读取二进制搜索树的黑客经常可以在实践中,非移植地以及依赖于内核版本的方式工作。也许使用低级非便携技巧(例如futexesatomic gcc builtins)序列化访问可能会有效。读取NPTL的(机器特定的)源代码,即当前的Linux pthread例程应该有所帮助。

可能是pthread_mutex_lock等实际上可以从Linux信号处理程序中使用的情况......(因为它可能只有futex和原子指令。)