如何理解独立 C 或 C++ 实现中的原子?
How to understand atomics in a freestanding C or C++ implementation?
C11 和 C++11 根据执行线程定义原子。虽然在托管环境中很清楚什么是线程,但在独立语言实现中它是一个相当模糊的术语。
- 如何在所有线程都必须在程序内部实现的独立实现中正式理解 C11 和 C++11 中指定的原子?例如:ISR 是一个单独的执行线程吗?
- 为什么标准委员会根据线程而不是简单地在代码排序领域定义原子?
- 除了 gcc 之外,是否有任何嵌入式编译器已经支持 C11/C++11 原子?
Atomics 用于处理竞争条件,因此如果没有线程,它们几乎毫无意义。唯一可能发生竞争的上下文是信号处理程序,C 标准提供了无锁的概念。
这样看来,独立环境和托管环境之间没有区别。线程和原子是可选特性,如果独立环境同时支持这两者,则它必须符合两者的规范。如果它只支持原子,它可以为信号处理程序提供无锁原子类型,但是其他原子类型就没用了。
我对这类问题的一些机械化(和一些手摇)方法是原子保证三件事:读取和写入不会被上下文切换撕裂(所以你只能看到实际存储在多变的);缓存被刷新(所以你看不到陈旧的值);并且编译器无法跨原子操作移动指令(因此逻辑上发生在原子访问之前的操作实际上发生在该访问之前)。请注意,我已尝试在此处避免任何 "thread" 的概念,尽管它有点费力。
如果您正在编写自己的线程机制,这些属性显然很重要。它们与您正在使用的线程机制的细节正交。
对于信号处理程序,当您需要检查在信号处理程序中执行的代码中的值时,以及当信号处理程序需要修改程序其余部分所关心的值时,它们会为您提供支持。
我不确定标准是否正式解决了 ISR(很确定没有),但从这个机制的角度来看,ISR 与不是来自对 [= 的调用的信号没有区别10=]。它只是一个异步函数调用,它占用从被中断的线程中获取的堆栈space。这绝对不是一个话题;它是现有线程上的寄生虫。因此,对于 ISR,我会选择信号保证而不是线程保证。
C11 和 C++11 根据执行线程定义原子。虽然在托管环境中很清楚什么是线程,但在独立语言实现中它是一个相当模糊的术语。
- 如何在所有线程都必须在程序内部实现的独立实现中正式理解 C11 和 C++11 中指定的原子?例如:ISR 是一个单独的执行线程吗?
- 为什么标准委员会根据线程而不是简单地在代码排序领域定义原子?
- 除了 gcc 之外,是否有任何嵌入式编译器已经支持 C11/C++11 原子?
Atomics 用于处理竞争条件,因此如果没有线程,它们几乎毫无意义。唯一可能发生竞争的上下文是信号处理程序,C 标准提供了无锁的概念。
这样看来,独立环境和托管环境之间没有区别。线程和原子是可选特性,如果独立环境同时支持这两者,则它必须符合两者的规范。如果它只支持原子,它可以为信号处理程序提供无锁原子类型,但是其他原子类型就没用了。
我对这类问题的一些机械化(和一些手摇)方法是原子保证三件事:读取和写入不会被上下文切换撕裂(所以你只能看到实际存储在多变的);缓存被刷新(所以你看不到陈旧的值);并且编译器无法跨原子操作移动指令(因此逻辑上发生在原子访问之前的操作实际上发生在该访问之前)。请注意,我已尝试在此处避免任何 "thread" 的概念,尽管它有点费力。
如果您正在编写自己的线程机制,这些属性显然很重要。它们与您正在使用的线程机制的细节正交。
对于信号处理程序,当您需要检查在信号处理程序中执行的代码中的值时,以及当信号处理程序需要修改程序其余部分所关心的值时,它们会为您提供支持。
我不确定标准是否正式解决了 ISR(很确定没有),但从这个机制的角度来看,ISR 与不是来自对 [= 的调用的信号没有区别10=]。它只是一个异步函数调用,它占用从被中断的线程中获取的堆栈space。这绝对不是一个话题;它是现有线程上的寄生虫。因此,对于 ISR,我会选择信号保证而不是线程保证。