15

据说您应该只在信号处理程序中调用异步安全函数。我的问题是,什么构成异步安全?我猜一个既可重入线程安全的函数是异步安全的?或者没有?

4

2 回答 2

14

重入和线程安全与此有一点关系或没有关系。这些功能的副作用、状态和中断是重要的事实。

异步安全函数[GNU Pth]

一个函数是异步安全的或异步信号安全的,前提是它可以在信号处理程序上下文中安全地调用且没有副作用。也就是说,它必须能够在任何点被中断以线性乱序运行而不会导致不一致的状态。当全局数据本身可能处于不一致状态时,它也必须正常工作。此处列出了一些异步安全操作:

  • 调用该signal()函数以重新安装信号处理程序
  • 无条件修改volatile sig_atomic_t变量(因为对这种类型的修改是原子的)
  • 调用该_Exit()函数立即终止程序执行
  • 调用由您的实现指定的异步安全函数

很少有函数是可移植的异步安全的。如果一个函数执行任何其他操作,它可能不是可移植的异步安全的。

一个经验法则是 - 仅从信号处理程序发出某些条件变量的信号(例如 futex/pthread 条件,唤醒 epoll 循环等)。

更新:

正如 EmployedRussian 所建议的那样,即使打电话pthread_cond_signal也是个坏主意。我检查了最近的源代码,eglibc里面有锁定/解锁对。因此,引入了死锁的可能性。这使我们几乎没有选择向其他线程发出信号:

  1. 使用eventfd.
  2. 更改全局原子变量并希望未设置 SA_RESTART 并且其他线程将检查我们的原子。
于 2011-12-13T17:04:45.860 回答
1

对于您自己的代码,是的,可重入和线程安全是您需要的特性,因为根据您设置信号处理机制的方式,您的信号处理程序本身可能会被另一个信号中断。一般来说,尽量在信号处理程序中做尽可能少的工作。设置标志以在您的正常程序流程中触发特殊代码可能是您应该做的所有事情。

对于您可能调用的操作系统中的函数,请查看man 7 signal可以安全调用的列表。请注意,malloc()并且free()不在列表中pthread 同步 API 也不在列表中,但我认为某些调用必须是安全的,因此您可以在信号处理程序中安全地设置全局标志。

于 2011-12-13T17:12:13.733 回答