sem_wait 和信号处理程序
为什么 sem_wait 不能在信号处理程序中使用(特别是每个线程的 SIGSEGV 信号)?有人可以给我一个会使应用程序崩溃的示例场景吗?我猜 sem_wait
既是可重入又是线程安全,那么这里的问题是什么?为什么它不异步安全?
Why sem_wait
cannot be used inside a signal handler (particularly SIGSEGV signal which is per thread)? Can someone give me an example scenario where it will crash the application? I guess sem_wait
is both reentrant and thread safe, so what is the problem here? Why is it not async safe?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
异步安全的要求比线程安全严格得多。您可以使用原语编写线程安全代码,以保护具有关键部分的全局数据。信号处理程序不能依赖于此。例如,您可能位于 sem_wait 的关键部分内,同时执行一些导致段错误的操作。这会破坏 sem_wait 的线程安全保护。
Async safe is a much stricter requirement than thread safe. You can write thread safe code using primitives to protect global data with critical sections. Signal handlers can't rely on this. For example, you could be inside a critical section within sem_wait, and simultaneously do something that causes a segfault. This would break the thread-safe protections of sem_wait.
由于以下原因,sem_wait 不能在信号处理程序中使用:
线程 A 在 sem1 上调用 sem_wait。当线程 A 完成后,它会发送到 sem1。但是,在完成之前,会收到信号,然后进入处理程序,在 sem1 上调用 sem_wait。由于 A 是发送到 sem1 的处理程序,因此处理程序将永远不会返回,并且您将陷入死锁。这就是为什么永远不要等待信号处理程序中的任何内容是一个好规则的原因。 ASFAIK,这个问题更多地与死锁有关,而不是崩溃。
此外,这违反了信号处理程序的理想目的,即处理外部中断,然后快速返回到您正在做的事情。
最后,摆脱 SIGSEGV 而不是处理它不是一个更好的目标吗?
sem_wait cannot be used in a signal handler for this reason:
Thread A is calls sem_wait on sem1. When thread A is done, it posts to sem1. However, before it can finish the signal is received and then handler is entered, calling sem_wait on sem1. Since A is the one that would post to sem1, the handler will never return and you will have deadlock. This is why it is a good rule to never wait on anything in a signal handler. The problem, ASFAIK, has more to do with deadlock than crashing.
Also, this violates the ideal purpose of a signal handler, which is to handle an external interrupt and then get back to what you were doing quickly.
Lastly, isn't it a better goal to rid yourself of the SIGSEGV instead of handling it?
如果应用程序在信号量值为零时接收到信号,并且接收信号的线程恰好是应该增加信号量值 (sem_post) 的线程,该怎么办?如果然后在信号处理程序中调用 sem_wait,进程将死锁,不是吗?
当然,另一个论点可能是,如果 sem_wait 不在异步信号安全函数列表中,则实现可以自由调用鼻恶魔。
What if the application receives a signal while the value of the semaphore is zero, and the thread that receives the signal happens to be the one which is supposed to increment the semaphore value (sem_post)? If you then call sem_wait in the signal handler, the process will deadlock, no?
Another argument could of course be that if sem_wait is not on the list of async-signal-safe functions, the implementation is free to invoke nasal demons.