From 93ce6490a60dc3b62d8a9c65e5dffe5589ccb200 Mon Sep 17 00:00:00 2001 From: Changkun Ou Date: Wed, 11 Aug 2021 13:10:34 +0200 Subject: [PATCH] book: revise release acquire semantics Fixes #174 --- book/en-us/07-thread.md | 5 +++-- book/zh-cn/07-thread.md | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/book/en-us/07-thread.md b/book/en-us/07-thread.md index 412e790..b9e5806 100644 --- a/book/en-us/07-thread.md +++ b/book/en-us/07-thread.md @@ -464,8 +464,9 @@ To achieve the ultimate performance and achieve consistency of various strength 3. Release/Acquire model: Under this model, we can further tighten the order of atomic operations between different threads, specifying the timing between releasing `std::memory_order_release` and getting `std::memory_order_acquire`. **All** write operations before the release operation is visible to any other thread, i.e., happens before. - As you can see, `std::memory_order_release` ensures that the write behavior after it does not occur before the release operation, which is a forward barrier, and`std::memory_order_acquire` ensures that its previous write behavior does not occur after this acquisition operation, there is a backward barrier. For the `std::memory_order_acq_rel` option, combines the characteristics of the two and uniquely determines a memory barrier, so that the current thread's reading and writing of memory will not be rearranged before and after this operation. - + As you can see, `std::memory_order_release` ensures that a write before a release does not occur after the release operation, which is a **backward barrier**, and `std::memory_order_acquire` ensures that a subsequent read or write after a acquire does not occur before the acquire operation, which is a **forward barrier**. + For the `std::memory_order_acq_rel` option, combines the characteristics of the two barriers and determines a unique memory barrier, such that reads and writes of the current thread will not be rearranged across the barrier. + Let's check an example: ```cpp diff --git a/book/zh-cn/07-thread.md b/book/zh-cn/07-thread.md index 1e81fd0..4eef992 100644 --- a/book/zh-cn/07-thread.md +++ b/book/zh-cn/07-thread.md @@ -472,9 +472,9 @@ int main() { consumer.join(); ``` -3. 释放/获取模型:在此模型下,我们可以进一步加紧对不同线程间原子操作的顺序的限制,在释放 `std::memory_order_release` 和获取 `std::memory_order_acquire` 之间规定时序,即发生在释放操作之前的**所有**写操作,对其他线程的任何获取操作都是可见的,亦即发生顺序(happens-before)。 +3. 释放/获取模型:在此模型下,我们可以进一步加紧对不同线程间原子操作的顺序的限制,在释放 `std::memory_order_release` 和获取 `std::memory_order_acquire` 之间规定时序,即发生在释放(release)操作之前的**所有**写操作,对其他线程的任何获取(acquire)操作都是可见的,亦即发生顺序(happens-before)。 - 可以看到,`std::memory_order_release` 确保了它之后的写行为不会发生在释放操作之前,是一个向前的屏障,而 `std::memory_order_acquire` 确保了它之前的写行为,不会发生在该获取操作之后,是一个向后的屏障。对于选项 `std::memory_order_acq_rel` 而言,则结合了这两者的特点,唯一确定了一个内存屏障,使得当前线程对内存的读写不会被重排到此操作的前后。 + 可以看到,`std::memory_order_release` 确保了它之前的写操作不会发生在释放操作之后,是一个向后的屏障(backward),而 `std::memory_order_acquire` 确保了它之前的写行为不会发生在该获取操作之后,是一个向前的屏障(forward)。对于选项 `std::memory_order_acq_rel` 而言,则结合了这两者的特点,唯一确定了一个内存屏障,使得当前线程对内存的读写不会被重排并越过此操作的前后: 我们来看一个例子: