#include
#include
int main(){
std::atomic v0 = 0;
std::atomic v = 0;
std::thread t1([&](){
v0.store(1,std::memory_order::relaxed); // A
v.store(2,std::memory_order::relaxed); // B
});
std::thread t2([&](){
v.load(std::memory_order::relaxed); // C
});
t1.join();
t2.join();
}
В этом примере в абстрактном смысле, если C читает 2 , можем ли мы сказать, что был выполнен по потоке T1 ? Мой аргумент заключается в том, что [intro.races] P10 говорит: < /p>
Значение атомного объекта M, как определено по оценке B, является значением, сохраняемое некоторыми неопределенными побочным эффектом A, которое модифицирует m < /strong>, где B не может существовать до. Производство 2 Такое, что C может прочитать 2 . В этой программе это должно быть b . Это означает, что оценка в b должна была быть выполнена потоком T1 для создания этого побочного эффекта; И наоборот, если B не был выполнен по потоке T1 , этот побочный эффект не может существовать.
intro.execution] p8 говорит:
sequened перед тем, что является асимметричным, транзитивным, паромным отношением между оценкой, выполненной в одиночной резьбе (Intro-indoUltiptiptiptiptiptiptiptiptiptiptiptiptiptiptions, Intro-indlactiptiptiptiptiptiptiptiptiption). (Intro Onductitiptiptiptiptiptiptiptiptiptiptiptiptiption). частичный порядок среди этих оценок. Given any two evaluations A and B, if A is sequenced before B (or, equivalently, B is sequenced after A), then the execution of A shall precede the execution of B.
Since B has been executed by thread t1, and A is sequenced before B, также уже был выполнен потоком T1 . в любом случае, за исключением того же потока, «выполняется», не означает «видимость/порядок» для других потоков. В частности, «оценка была выполнена потоком» (с именем Q ) является необходимым условием «побочного эффекта, создаваемого оценкой, видна другому потоку» (с именем p ). То есть P-> Q , но не наоборот. Однако это изменение не является наблюдаемым поведением в этой программе; Если на v0 была атомная нагрузка, а после C , а нагрузка должна была прочитать 0 , мы не могли бы различить, что это потому, что и b были переупорядочены так, что не был выполнен по потоке T1 или только то, что D был выполнен до Code>. /> Более того, этот вопрос только фокусируется на абстрактном компьютере , и в этом смысле нет переупорядочения. Подумайте в обратном направлении, если бы этот вывод был неверным, мы бы показали, что B был выполнен по потоке T1 (этим управляет [intro.races] p10), а не был выполнен T1 ; Однако поток управления T1 не может достичь b , если он не завершил выполнение (этим управляет
ninmin.excution] p8), что противоречит, в любом случае, в абстрактной машине.>
Рассмотрим этот пример: < /p> [code]#include #include
int main(){ std::atomic v0 = 0; std::atomic v = 0; std::thread t1([&](){ v0.store(1,std::memory_order::relaxed); // A v.store(2,std::memory_order::relaxed); // B }); std::thread t2([&](){ v.load(std::memory_order::relaxed); // C }); t1.join(); t2.join(); } [/code] В этом примере в абстрактном смысле, если C читает 2 , можем ли мы сказать, что был выполнен по потоке T1 ? Мой аргумент заключается в том, что [intro.races] P10 говорит: < /p>
Значение атомного объекта M, как определено по оценке B, является значением, сохраняемое некоторыми неопределенными [b] побочным эффектом A, которое модифицирует m < /strong>, где B не может существовать до. Производство 2 Такое, что C может прочитать 2 . В этой программе это должно быть b . Это означает, что оценка в b должна была быть выполнена потоком T1 для создания этого побочного эффекта; И наоборот, если B не был выполнен по потоке T1 , этот побочный эффект не может существовать. intro.execution] p8 говорит:
sequened перед тем, что является асимметричным, транзитивным, паромным отношением между оценкой, выполненной в одиночной резьбе (Intro-indoUltiptiptiptiptiptiptiptiptiptiptiptiptiptiptions, Intro-indlactiptiptiptiptiptiptiptiptiption). (Intro Onductitiptiptiptiptiptiptiptiptiptiptiptiptiption). частичный порядок среди этих оценок. Given any two evaluations A and B, if A is sequenced before B[/b] (or, equivalently, B is sequenced after A), then [b]the execution of A shall precede the execution of B[/b].
Since B has been executed by thread t1, and A is sequenced before B, также уже был выполнен потоком T1 . [b] в любом случае, за исключением того же потока, «выполняется», не означает «видимость/порядок» для других потоков. В частности, «оценка была выполнена потоком» (с именем Q ) является необходимым условием «побочного эффекта, создаваемого оценкой, видна другому потоку» (с именем p ). То есть P-> Q , но не наоборот. Однако это изменение не является наблюдаемым поведением в этой программе; Если на v0 была атомная нагрузка, а после C , а нагрузка должна была прочитать 0 , мы не могли бы различить, что это потому, что и b были переупорядочены так, что не был выполнен по потоке T1 или только то, что D был выполнен до Code>. /> Более того, этот вопрос только фокусируется на абстрактном компьютере [/b], и в этом смысле нет переупорядочения. Подумайте в обратном направлении, если бы этот вывод был неверным, мы бы показали, что B был выполнен по потоке T1 (этим управляет [intro.races] p10), а не был выполнен T1 ; Однако поток управления T1 не может достичь b , если он не завершил выполнение (этим управляет ninmin.excution] p8), что противоречит, в любом случае, в абстрактной машине.>