Ответ 1
С++ 0x paper N2427 (atomics) утверждает примерно следующее. Я немного изменил формулировку, поэтому ее легче читать для конкретной ситуации декремента, части, которые я изменил, находятся в жирным:
Эффекты: Атомно заменить значение в объекте результатом декремента, применяемого к значению в объекте и заданном операнде. Память зависит от порядка. Эти операции - операции чтения-изменения-записи в смысле определения "синхронизируются с" в [новом разделе, добавленном N2334 или преемником], и, следовательно, обе такие операции и оценка, которые дали входное значение, синхронизируются с любой оценкой, которая читает обновленное значение.
Возвращает: Атомно значение объекта непосредственно перед декретом.
Атомная операция гарантирует, что оператор декремента вернет значение, которое переменная удерживается непосредственно перед операцией, это атомарно, поэтому промежуточное значение из обновлений другим промежуточным значением не может быть.
Это означает, что единственные возможные исполнения этого кода с двумя потоками:
(Initial Value: 1)
Thread 1: Decrement
Thread 1: Compare, value is 0, enter region of interest
Thread 2: Decrement
Thread 2: Compare, value is -1, don't enter region
или
(Initial Value: 1)
Thread 1: Decrement
Thread 2: Decrement
Thread 1: Compare, value is 0, enter region of interest
Thread 2: Compare, value is -1, don't enter region
Случай 1 - это неинтересный ожидаемый случай.
Случай 2 перемежает операции декремента и выполняет последующие операции сравнения. Поскольку операция декремента и выборки является атомарной, для потока 1 невозможно получить значение, отличное от 0 для сравнения. Он не может получить -1, потому что операция была атомарной... чтение происходит во время декремента, а не во время сравнения. Больше потоков не изменит этого поведения.