我想知道从信号处理程序访问共享数据是否是个好主意。我的意思是考虑具有单个过程的多进程系统和多线程系统的场景。在多进程系统中,假设我让进程处理特定信号并通过进程更新某些共享变量或内存。我可以从信号处理程序本身那样做。
但是,对于使用pthreads的线程,我不认为它是可行的。 http://maxim.int.ru/bookshelf/PthreadsProgram/htm/r_40.html。正如本文所述,他们已经提到它不是异步信号安全的,并建议使用sigwait。我不是为什么它不是异步信号安全。我的意思是说,我通过线程处理信号并处于信号处理程序路由中。我获取了共享内存上的锁以更新它。同时,另一个相同类型的信号到达,另一个负责处理它的线程再次执行信号处理程序。这里的信号处理程序对于进程是相同的,但它被多次调用。第二次,它无法看到锁定并更新/覆盖数据。这是使用共享数据的多线程信号处理程序的问题。
我有点困惑,在多进程系统中,我有每个进程的信号处理程序的副本。但是在多线程系统中,有多个线程使用的信号处理程序的单个副本不是它。因此,当相同类型的多个信号到来并且我们有两个负责处理它的线程尝试处理它时,它们都将尝试执行相同的处理程序代码?它是如何适应的?
答案 0 :(得分:5)
我仔细阅读了您引用的文章,并在 “信号处理程序中的主题” 部分中找到了一些有趣的信息。在该部分中,您将看到它们具有可以从信号处理程序中进行的Posix函数调用列表。然后不久,他们提到了以下内容:
但是Pthreads在哪里打电话?他们不在其中任何一个 名单!实际上,Pthreads标准指定了行为 从a调用函数时,所有Pthreads函数都是未定义的 信号处理器。如果您的处理程序需要操作数据 与其他线程共享≈缓冲区,标志或状态变量的基础 好运Pthreads互斥和条件变量同步 电话不受限制。
注意最后一句:“Pthreads互斥和条件变量同步调用是禁止的”
可以从信号处理程序调用的上述函数描述如下:
这些函数有一个称为reentrancy的特殊属性 允许进程对这些正在进行的功能进行多次调用 在同一时间。
pthread同步函数没有称为reentrancy的特殊属性,所以我想如果这些函数(例如pthread_mutex_lock())被到达的信号中断,那么行为就不是“安全的”。
想象一下,您的应用程序调用{{1}}并且恰好在那一刻(即在pthread_mutex_lock()函数中)信号到达。如果信号处理程序也调用pthread_mutex_lock(&theMutex)
,则前一个pthread调用可能没有终止,因此无法保证对pthread_mutex_lock()的哪个调用将获得锁定。因此产生的行为将是未定义/不确定的。
我认为从特定线程调用sigwait()可以保证没有重要的pthread_mutex_lock(&theMutex)
函数调用可能被中断,从而允许调用pthread同步函数是“安全的”。