据说您只应在信号处理程序中调用异步安全函数。我的问题是,异步安全的构成是什么? 可重入和线程安全的功能异步安全我猜?还是不?
答案 0 :(得分:12)
重新进入和螺纹安全与此有点或无关。这些功能的副作用,状态和中断是重要的事实。
asynchronous-safe function [GNU Pth]
一个函数是异步安全的, 或异步信号安全,如果它可以安全地和没有 信号处理程序上下文中的副作用。也就是说,它一定是 能够在任何点上被中断以不按顺序线性运行 不会造成不一致的状态。它也必须正常运作 当全局数据本身可能处于不一致状态时。一些 此处列出了异步安全操作:
- 调用
signal()
函数重新安装信号处理程序- 无条件修改
volatile sig_atomic_t
变量(如 对此类型的修改是原子的)- 调用
_Exit()
函数 立即终止程序执行- 调用异步安全 函数,由您的实现指定
很少有功能 可移植的异步安全。如果函数执行任何其他功能 操作,它可能不是可移植的异步安全。
经验法则是这样 - 仅从信号处理程序发出一些条件变量(例如futex / pthread条件,唤醒epoll循环等)。
<强>更新强>
正如EmployedRussian建议的那样,即使调用pthread_cond_signal
也是个坏主意。我检查了最近eglibc
的源代码,并且在那里有锁定/解锁对。因此,引入了死锁的可能性。这使我们几乎没有选择信号通知其他线程:
eventfd
。答案 1 :(得分:1)
对于您自己的代码,是的,重入和线程安全是您需要的特性,因为根据您设置信号处理机制的方式,您的信号处理程序本身可能会被另一个信号中断。通常,尽量在信号处理程序中尽可能少地完成工作。设置标志以在正常程序流程中触发特殊代码可能就是你应该做的全部。
对于您可能呼叫的操作系统中的功能,请查看man 7 signal
以获取可安全呼叫的列表。请注意,列表中的malloc()
和free()
不是。 pthread同步API也不在列表中,但我认为有些API必须是安全的,所以你可以在信号处理程序中安全地设置一个全局标志。