Как официально доказать, что заявление после спиновой петли не выполнено, если не обменяется другой поток, с расслабленнC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как официально доказать, что заявление после спиновой петли не выполнено, если не обменяется другой поток, с расслабленн

Сообщение Anonymous »

Рассмотрим этот пример: < /p>

Код: Выделить всё

#include 
#include 
#include 

int main(){
std::atomic v = 0;
std::atomic flag = false;
std::thread t1([&](){
while(!flag.load(std::memory_order::relaxed)){}  // #1
assert(v.exchange(2,std::memory_order::relaxed) == 1);  // #2
});
std::thread t2([&](){
if(v.exchange(1,std::memory_order::relaxed) == 0){ // #3
flag.store(true, std::memory_order::relaxed); // #4
}
});
t1.join();
t2.join();
}
< /code>
Простой способ доказать, что утверждение никогда не проходит,-это использовать противоположность. Цель состоит в том, чтобы доказать, что «если утверждение выполнено, условие в if 
должно быть правдой». Эквивалентно, «если условие в if верно, утверждение не будет выполнено». Первое заместимость выполняется. If the else part of the selection statement is present and the condition yields false, the second substatement is executed.

The infinite loop can exit only if its condition loads true according to [stmt.while] p1 says:

In the while statement, the substatement is executed repeatedly until the value of the Условие ([[stmt.pre]) становится ложным.

то есть, должен существовать побочный эффект, который устанавливает флаг true , который управляется [Intro.races] p10

Некоторые неопределенные побочные эффекты A, который изменяет M, где B не происходит до A.

Побочный эффект может быть получен только с помощью оценки в #4 , и что оценка должна быть выполнена для создания побочного эффекта.
, как и сейчас, каждая шаг формального анализа соответствует формальному правилу. Тем не менее, я не могу найти соответствующее формальное правило, которое имеет отношение к «утверждению недоступно/не будет выполнено, если цикл не выходит», которое может получить следующее предложение вместе с вышеуказанными шагами:

, если утверждение было выполнено, условие в if true. Критический шаг в этом формальном противостоянии. Наконец, в соответствии с [atomics.order] p10 < /p>

Операции атомного чтения-модификации-записи всегда должны считывать последнее значение (в порядке модификации), написанного до записи, связанной с операцией по считыванию-модификации. 0 , поэтому RMW на #3 должен прочитать 2 , что приводит к тому, что условие является false , следовательно, предположение о ложном. /> Обновление: < /h3>
Если #1 < /code> был простым оператором выражения, например: < /p>

Код: Выделить всё

flag.load(std::memory_order::relaxed); // #1
assert(v.exchange(2,std::memory_order::relaxed) == 1); // #2
Сравните эти два случая: Является ли общая точка, что #2 не будет выполнено, пока #1 завершит его выполнение? Это разница, что в случае цикла выполнение #1 может иметь бесконечное количество шагов, так что его выполнение никогда не завершается, что приводит к #2 никогда не выполняется; Вместо этого, в случае простого оператора выражения, #1 может иметь только конечное количество шагов для выполнения, так что #2 Всегда можно добраться? instead, in the simple expression statement, the implementation can be arbitrary to reorder #1 and #2, because the reordering won't violate the observable behavior, for example, #2 reads 1 and #1 reads false, we cannot distinguish it because #2 is executed before #1(reordered by implementation), or just #1 является когерентным упорядоченным, прежде чем #4 . Это правильное понимание?


Подробнее здесь: https://stackoverflow.com/questions/797 ... d-unless-a
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»