Я не уверен, каковы границы барьеров памяти std::memory_order_release
или std::memory_order_acquire
.Ниже приведен пример из cppreference .Я подправил код, чтобы сделать мою точку зрения:
#include <atomic>
#include <cassert>
#include <string>
#include <thread>
#include <iostream>
std::atomic<std::string*> ptr;
void producer()
{
std::string* p = new std::string("Hello");
ptr.store(p, std::memory_order_release);
}
bool acquire(std::string* p2)
{
while (!(p2 = ptr.load(std::memory_order_acquire)));
return p2 != nullptr;
}
void consumer()
{
std::string* p2 {nullptr};
// while (!(p2 = ptr.load(std::memory_order_acquire))); // prints "makes sense"
assert(acquire(p2)); // prints "what's going on?"
if (p2 == nullptr)
{
std::cout << "what's going on?" << std::endl;
}
else
{
std::cout << "makes sense" << std::endl;
}
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
}
Вывод приведенного выше кода what's going on?
Я знаком (не эксперт) с барьерами памяти.Из приведенного выше теста у меня есть следующие вопросы:
std::memory_order_acquire
, используемый в функции acquire()
, используется только для области действия acquire()
, основываясь на результатах программыпоскольку uncommenting while(...)
печатает ожидаемый вывод, "имеет смысл".Имеет ли это смысл?я что-то упускаю?
Как можно напечатать "что происходит?", assert(acquire(p2))
дает понять, что p2 не nullptr
, но каким-то образом читает *Значение 1025 * в условном выражении if
.Я не эксперт по правилам исполнения ордеров, но я ожидаю, что p2 = nullptr
будет признано, прежде чем вызывать acquire()
, since acquire()
зависит от этого.