了解发布顺序并在 C11 中同步
Understanding release sequence and synchronize with in C11
我正在尝试理解内存模型并阅读 5.1.2.4 Multi-threaded executions and data races
,但对 5.1.2.4(p10)
中定义的释放序列概念感到困惑,如下所示:
A release sequence headed by a release operation A
on an atomic object
M
is a maximal contiguous sub-sequence of side effects in the
modification order of M
, where the first operation is A
and every
subsequent operation either is performed by the same thread that
performed the release or is an atomic read-modify-write operation.
随后用于在 5.1.2.4(p11)
处定义同步,如下所示:
Certain library calls synchronize with other library calls performed
by another thread. In particular, an atomic operation A
that
performs a release operation on an object M
synchronizes with an
atomic operation B
that performs an acquire operation on M
and
reads a value written by any side effect in the release sequence
headed by A
.
我可以想象下面的例子:
#include <stdatomic.h>
Atomic_ int a; // <<--- M
int main(void){
atomic_store_explicit(&a, 42, memory_order_release); // <<--- A
atomic_store_explicit(&a, 442, memory_order_release);
atomic_store_explicit(&a, 242, memory_order_release);
int a_value = atomic_load_explicit(&a, memory_order_acquire);
atomic_store_explicit(&a, 242, memory_order_release);
}
我目前理解为A
为atomic_store_explicit(&a, 42, memory_order_release);
,发布顺序为
atomic_store_explicit(&a, 442, memory_order_release);
atomic_store_explicit(&a, 242, memory_order_release);
但是 atomic_store_explicit(&a, 242, memory_order_release);
不包括在内,因为它后面跟着 int a_value = atomic_load_explicit(&a, memory_order_acquire);
,这是一个获取操作。
现在进入synchronize with
一个对对象M执行释放操作的原子操作A与对M执行获取操作并读取写入值的原子操作B同步by any side effect in the release sequence in the leaded by A. 表示 A 的释放序列中的所有释放操作都可以通过获取操作看到,即 atomic_load_explicit(&a, memory_order_acquire);
它是正确的还是我漏掉了什么?
不,该序列包括所有四个存储操作,因为中间加载操作是由同一个线程完成的。基本上对于您的示例,您不必参考同步。由于游戏中只有一个线程,"sequenced before" 已经为您提供了所有您想要的信息。优化器甚至可以省略简化示例中除最后一个之外的所有商店,即使对于原子操作也是如此。 (好吧,atomic_store
的规范中有 volatile
,但我们暂时忘掉它。)
我认为,释放序列概念的思想是识别不同线程的读取可能拦截存储值的点,并在序列中的第一个存储操作之后使读取依赖排序。为此,可以忽略线程读取它写入的值这一事实。
我正在尝试理解内存模型并阅读 5.1.2.4 Multi-threaded executions and data races
,但对 5.1.2.4(p10)
中定义的释放序列概念感到困惑,如下所示:
A release sequence headed by a release operation
A
on an atomic objectM
is a maximal contiguous sub-sequence of side effects in the modification order ofM
, where the first operation isA
and every subsequent operation either is performed by the same thread that performed the release or is an atomic read-modify-write operation.
随后用于在 5.1.2.4(p11)
处定义同步,如下所示:
Certain library calls synchronize with other library calls performed by another thread. In particular, an atomic operation
A
that performs a release operation on an objectM
synchronizes with an atomic operationB
that performs an acquire operation onM
and reads a value written by any side effect in the release sequence headed byA
.
我可以想象下面的例子:
#include <stdatomic.h>
Atomic_ int a; // <<--- M
int main(void){
atomic_store_explicit(&a, 42, memory_order_release); // <<--- A
atomic_store_explicit(&a, 442, memory_order_release);
atomic_store_explicit(&a, 242, memory_order_release);
int a_value = atomic_load_explicit(&a, memory_order_acquire);
atomic_store_explicit(&a, 242, memory_order_release);
}
我目前理解为A
为atomic_store_explicit(&a, 42, memory_order_release);
,发布顺序为
atomic_store_explicit(&a, 442, memory_order_release);
atomic_store_explicit(&a, 242, memory_order_release);
但是 atomic_store_explicit(&a, 242, memory_order_release);
不包括在内,因为它后面跟着 int a_value = atomic_load_explicit(&a, memory_order_acquire);
,这是一个获取操作。
现在进入synchronize with
一个对对象M执行释放操作的原子操作A与对M执行获取操作并读取写入值的原子操作B同步by any side effect in the release sequence in the leaded by A. 表示 A 的释放序列中的所有释放操作都可以通过获取操作看到,即 atomic_load_explicit(&a, memory_order_acquire);
它是正确的还是我漏掉了什么?
不,该序列包括所有四个存储操作,因为中间加载操作是由同一个线程完成的。基本上对于您的示例,您不必参考同步。由于游戏中只有一个线程,"sequenced before" 已经为您提供了所有您想要的信息。优化器甚至可以省略简化示例中除最后一个之外的所有商店,即使对于原子操作也是如此。 (好吧,atomic_store
的规范中有 volatile
,但我们暂时忘掉它。)
我认为,释放序列概念的思想是识别不同线程的读取可能拦截存储值的点,并在序列中的第一个存储操作之后使读取依赖排序。为此,可以忽略线程读取它写入的值这一事实。