Это дополнительный вопрос к этому .
Я хочу точно определить смысл порядка команд и то, как на него влияют std::memory_order_acquire
, std::memory_order_release
et c ...
В вопросе, который я связал, уже предоставлены некоторые детали, но я чувствовал, что предоставленный ответ на самом деле не о порядке (который был больше, чем я искал), а скорее немного мотивируя, почему это необходимо, et c.
Я приведу тот же пример, который я буду использовать в качестве ссылки
#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();
}
В двух словах, я хочу понять, что именно происходит с порядком команд в обеих строках
ptr.store(p, std::memory_order_release);
и
while (!(p2 = ptr.load(std::memory_order_acquire)))
Сосредоточение на первом согласно документации
... нет чтения или записи в текущем потоке могут быть переупорядочены после этого хранилища ...
Я смотрел несколько выступлений, чтобы понять эту проблему заказа, я понимаю, почему это важно сейчас. То, что я пока не могу понять, как компилятор переводит спецификацию порядка, я думаю, что пример, приведенный в документации, также не особенно полезен, потому что после операции сохранения в потоке, выполняющем producer
, нет другой инструкции, следовательно, ничего будет переупорядочен в любом случае. Однако также возможно, что я неправильно понимаю, возможно, они означают, что эквивалентная сборка
std::string* p = new std::string("Hello");
data = 42;
ptr.store(p, std::memory_order_release);
будет такой, что первые две переведенные строки никогда не будут перемещены после хранилища atomi c? Аналогично в потоке, работающем с производителем, возможно ли, что ни одно из утверждений (или эквивалентной сборки) никогда не будет перемещено до загрузки атома c? Предположим, у меня была третья инструкция после магазина, что будет с этой инструкцией, которая будет уже после загрузки atomi c?
Я также попытался скомпилировать такой код, чтобы сохранить код промежуточной сборки с флаг -S
, но он довольно большой, и я не могу понять.
Опять же, чтобы уточнить, этот вопрос о том, как упорядочение, а не о том, почему эти механизмы полезны или необходимы.