我知道这段代码是正确的(除了没有执行
delete
)。#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();
}
然而,我想知道为什么在消费者线程中数据不能是旧数据。这是因为acquire
操作吗?
ptr
提供的屏障的保护吗? - Lightness Races in Orbitstd::string
构造函数对对象的成员进行了一堆赋值操作。我想你不会感到惊讶,一旦consumer
获取了ptr
指针,它就会看到*ptr
的完全初始化状态。这与data
起作用的原因相同。 - Igor Tandetnikstd::atomic
+memory_order_release
只是为了防止编译时重排序,机器代码没有区别。如果您不想使用std::atomic
,则使用带有虚拟asm("":::"memory")
的普通变量就足够了。 - llllllllll