sem_wait和信号处理程序

4

为什么 sem_wait 不能在信号处理程序中使用(特别是每个线程的 SIGSEGV 信号)?有人能给我一个会导致应用崩溃的示例场景吗?我猜想 sem_wait 同时具备可重入性线程安全,那么问题出在哪里呢?它为什么不是异步信号安全呢?


我建议您添加信号量应该保护哪种类型的操作(线程、中断、异常等)。这会产生很大的影响。 - gnometorule
3个回答

4

异步安全是比线程安全要求更严格的。您可以使用原语编写线程安全的代码来保护全局数据,使用关键部分进行保护。但是信号处理程序不能依赖于此。例如,您可能会在sem_wait中的关键部分内,并同时执行某些导致段错误的操作。这将破坏sem_wait的线程安全保护。


2

由于以下原因,sem_wait不能在信号处理程序中使用:

线程A调用sem_wait等待sem1。当线程A完成后,它会对sem1进行发布。然而,在完成之前,接收到信号并进入处理程序,调用sem_wait等待sem1。由于A将对sem1进行发布,处理程序将永远无法返回,导致死锁。这就是为什么绝不要在信号处理程序中等待任何内容的好规则。据我所知,这个问题与死锁有关而非崩溃。

此外,这违反了信号处理程序的理想目的,即处理外部中断,然后尽快返回正在进行的工作。

最后,摆脱SIGSEGV不是更好的目标吗?


1
如果应用程序在信号量值为零时接收到信号,而接收信号的线程恰好是应该增加信号量值(sem_post)的线程,会发生什么情况?如果你在信号处理程序中调用sem_wait,进程将死锁,不是吗?
当然,另一个论点是,如果sem_wait不在异步信号安全函数列表中,实现可以自由地调用鼻腔恶魔。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接