我在一个情况下,我需要阅读的信号处理器(SIGSEGV信号处理程序,据我所知这是每个线程基地)内的二叉搜索树(BST)内共享数据。 BST可以由应用程序中的其他线程修改。读信号处理程序
现在既然信号处理程序不能使用信号量,互斥锁等,因此无法访问共享数据,我该如何解决这个问题?请注意,我的应用程序是多线程并在多核系统上运行。
我在一个情况下,我需要阅读的信号处理器(SIGSEGV信号处理程序,据我所知这是每个线程基地)内的二叉搜索树(BST)内共享数据。 BST可以由应用程序中的其他线程修改。读信号处理程序
现在既然信号处理程序不能使用信号量,互斥锁等,因此无法访问共享数据,我该如何解决这个问题?请注意,我的应用程序是多线程并在多核系统上运行。
您不应该从信号处理程序访问共享数据。你可以找到关于信号的详细信息在下面的文章:
Linux Signals for the Application Programmer
The Linux Signals Handling Model
貌似以应对Linux的信号至今signalfd最安全的方式。
假设SH不能直接访问共享数据,那么也许你可以做到这一点间接:
如果你担心重叠SIGSEGVs,计数器加进来跟踪。 (嘿!你刚刚建立了你自己的信号量!)
这里的薄弱环节显然是轮询,但它是一个开始。
我在想同样的事情:-p!但是当一个线程在信号发生时修改BST会发生什么。这一点有点令人担忧。 – MetallicPriest
我认为这不会是一个问题:信号会被抓住,设置标志并返回;该线程将继续修改BST,并且不会尝试“处理”信号,直到完成修改为止。假设这种修改是原子的,那看起来是一个合理的结果。 –
您可能会考虑mmap -ing a fuse文件系统(在用户空间中)。
其实,你会在Gnu Hurd更幸福这对于external pagers
或许你在你的信号处理函数读二叉搜索树砍支持往往可以在实际工作中,非便携和内核版本依赖的方式。也许序列化访问与低级别的非便携式技巧(例如futexes和atomic gcc builtins)可能工作。阅读NPTL(特定机器)的源代码,即当前的Linux pthread例程应该有所帮助。
这可能是pthread_mutex_lock
等实际上可以从Linux信号处理程序中使用的情况......(因为它可能只有futex
和原子指令)。
我提到了一些非移动技巧和Gnu赫德... –
我可以看到两个很干净的解决方案:
我会努力想办法不读取该信号处理程序中的共享数据。 – dbeer
为了强调@dbeer的要点,在信号处理程序中,您通常不应该做任何会阻止或引发其他信号或任何冗长操作的任何操作。信号处理程序应该很小,很快且很短。 –
也许我错过了一些东西,但是如果只有程序的线程访问共享内存(没有其他中断和异常),为什么不使用信号量(不管它是不错的风格是一个不同的问题)?如果一个线程访问关键区域,阻塞它,被另一个线程休眠,信号量仍然被锁定为另一个线程,并且最终您的初始线程将被安排再次访问它。除了性能方面的原因,我认为既没有数据损坏的危险,也没有拖延系统。 – gnometorule