C 什么构成异步安全性

C 什么构成异步安全性,c,linux,asynchronous,synchronization,signal-handling,C,Linux,Asynchronous,Synchronization,Signal Handling,据说您应该只调用信号处理程序中的异步安全函数。我的问题是,什么构成了异步安全性?一个可重入且线程安全的函数是异步安全的?或者没有?重新进入和线程安全与此有一点关系,或者根本没有关系。这些功能的副作用、状态和中断是重要的事实 [GNU Pth] 函数是异步安全的, 或者异步信号安全,如果可以安全且无需 信号处理程序上下文中的副作用。就是一定是 能够在任意点中断,以线性顺序运行 不会造成不一致的状态。它还必须正常工作 当全局数据本身可能处于不一致状态时。一些 此处列出了异步安全操作: 调用sign

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

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

[GNU Pth]

函数是异步安全的, 或者异步信号安全,如果可以安全且无需 信号处理程序上下文中的副作用。就是一定是 能够在任意点中断,以线性顺序运行 不会造成不一致的状态。它还必须正常工作 当全局数据本身可能处于不一致状态时。一些 此处列出了异步安全操作:

  • 调用
    signal()
    函数重新安装信号处理程序
  • 无条件修改
    易失性sig\u原子\u t
    变量(如 对此类型的修改是原子的)
  • 调用
    \u Exit()
    函数 立即终止程序执行
  • 调用异步安全机制 函数,由您的实现指定
很少有函数是可用的 可移植异步安全。如果函数执行任何其他 操作,它可能不是可移植的异步安全的

一个经验法则是,只从信号处理程序中发出一些条件变量的信号(例如futex/pthread condition、wake-up-epoll循环等)

更新:

正如EmployedRussian所建议的,即使调用
pthread\u cond\u signal
也是一个坏主意。我已经检查了最近的
eglibc
的源代码,其中有一个锁定/解锁对。因此,引入了僵局的可能性。这使得我们几乎没有其他选项来通知其他线程:

  • 使用
  • 更改全局原子变量,并希望未设置sau RESTART,其他线程将检查我们的原子变量

  • 对于您自己的代码,是的,可重入和线程安全是您需要的特性,因为根据您如何设置信号处理机制,您的信号处理程序本身可能会被另一个信号中断。通常,在信号处理程序中尽量少做工作。在您的正常程序流中设置触发特殊代码的标志可能就是您应该做的全部工作


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

    Found。因此,函数可能不使用全局变量(原子类型除外),在任何时候中断它都会使进程处于一致状态。如果您访问线程本地内容,您将与线程竞争,您将中断并可能导致数据损坏。有一个更大的函数列表(您必须向下滚动一点以查看列表),包括大多数传统的Unix“系统调用”,以及对
    errno
    的访问。另外,如果您知道只有在正常执行被阻止时才会调用信号处理程序,那么在处理程序中执行任意操作是安全的。
    pthread*
    函数都不是异步信号安全的,因此“signal pthread condition variable”是一个错误的建议(TM)。@EmployedRussian:这并不是不安全,它可能不会唤醒等待POSIX条件变量的人。@EmployedRussian:事实上,我收回我的话-只是检查了源代码,这可能会导致死锁:-),所以我想唯一安全的唤醒是通过fcntl和/或原子变量。从信号处理程序唤醒
    select
    样式的主循环的常用技巧是将一个字节写入感兴趣的fds集中的管道。可能也有兴趣。