与关系的同步到底是什么?
我一直在阅读这篇文章关系,以及 std:std: :memory_order 来自CPP参考的页面,我并不真正理解:
看来,标准有某种希望,我不明白为什么有必要。让我们以CPP参考为例:
#include <thread>
#include <atomic>
#include <cassert>
#include <string>
std::atomic<std::string*> ptr;
int data;
void producer()
{
std::string* p = new std::string("Hello");
data = 42;
ptr.store(p, std::memory_order_release);
}
void consumer()
{
std::string* p2;
while (!(p2 = ptr.load(std::memory_order_acquire)))
;
assert(*p2 == "Hello"); // never fires
assert(data == 42); // never fires
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
}
参考说明:
如果线程A中的原子存储是标记为MEMORY_ORDER_ORDER_RELEASE和来自同一变量的螺纹B中的原子负载,则标记为Memory_order_Acquire,所有内存写入(非原子和放松的原子)在原子商店之前就发生了 - 线程A的视图,在线程B中变为可见的副作用。也就是说,一旦原子负载完成,螺纹B保证可以看到所有线程写入内存的所有内容。仅当b实际返回存储的值或发行顺序后期的值。
中的值才能保持。。
据我所知,当我们
ptr.store(p, std::memory_order_release)
实际在做什么是在告诉编译器和CPU时,运行时,可以做到data
,并且内存指向< Code> std :: String* P 将在ptr
的新值中可见。
同样的是,当我们
ptr.load(std::memory_order_acquire)
告诉编译器和CPU时:使其成为ptr
的加载,不会更晚于*p2
和data
的加载< /代码>。
所以我不明白我们在这里有什么进一步的承诺?
I've been reading this post of Jeff Preshing about The Synchronizes-With Relation, and also the "Release-Acquire Ordering" section in the std::memory_order page from cpp reference, and I don't really understand:
It seems that there is some kind of promise by the standard that I don't understand why it's necessary. Let's take the example from the CPP reference:
#include <thread>
#include <atomic>
#include <cassert>
#include <string>
std::atomic<std::string*> ptr;
int data;
void producer()
{
std::string* p = new std::string("Hello");
data = 42;
ptr.store(p, std::memory_order_release);
}
void consumer()
{
std::string* p2;
while (!(p2 = ptr.load(std::memory_order_acquire)))
;
assert(*p2 == "Hello"); // never fires
assert(data == 42); // never fires
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
}
The reference explains that:
If an atomic store in thread A is tagged memory_order_release and an atomic load in thread B from the same variable is tagged memory_order_acquire, all memory writes (non-atomic and relaxed atomic) that happened-before the atomic store from the point of view of thread A, become visible side-effects in thread B. That is, once the atomic load is completed, thread B is guaranteed to see everything thread A wrote to memory. This promise only holds if B actually returns the value that A stored, or a value from later in the release sequence.
as far as I understand, when we
ptr.store(p, std::memory_order_release)
What we're actually doing is telling both the compiler and the CPU that when running, make it so there will be no way that data
and the memory pointed to by std::string* p
will be visible AFTER the new value of ptr
will be visible to thread t2.
And same, when we
ptr.load(std::memory_order_acquire)
We are telling the compiler and CPU: make it so the loading of ptr
will be no later than then loading of *p2
and data
.
So I don't understand what further promise we have here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此
ptr.store(p,std :: memory_order_release)
(l1)保证,只要其他线程是其他线程,其他线程都可以看到此特定线程(t1)中此行之前完成的任何操作读取ptr
以正确的方式读取(在这种情况下,使用std :: memory_order_acquire
)。此保证只能与这对合作,仅此行保证了什么都没有保证。现在,您在另一个线程(t2)上拥有
ptr.load(std :: memory_order_acquire)
(l2),该线程(t2)与另一个线程一起使用其对,保证只要它读取在用中读取的值T1您可以在该行之前看到其他值(在您的情况下,是data
)。因此,因为L1 与 l2同步,data = 42;
发生在assert(data == 42)
之前。另外,可以保证
ptr
是在原子上写下和读取的,因为它是原子。该代码中没有其他保证或承诺。This
ptr.store(p, std::memory_order_release)
(L1) guarantees that anything done prior to this line in this particular thread (T1) will be visible to other threads as long as those other threads are readingptr
in a correct fashion (in this case, usingstd::memory_order_acquire
). This guarantee works only with this pair, alone this line guarantees nothing.Now you have
ptr.load(std::memory_order_acquire)
(L2) on the other thread (T2) which, working with its pair from another thread, guarantees that as long as it read the value written in T1 you can see other values written prior to that line (in your case it isdata
). So because L1 synchronizes with L2,data = 42;
happens beforeassert(data == 42)
.Also there is a guarantee that
ptr
is written and read atomically, because, well, it is atomic. No other guarantees or promises are in that code.