Может ли вытесняющая многозадачность мешать семантике получения-релиза C ++ 11?

Возможно ли (теоретически) для потока выполнить acquire на одном процессоре, а затем немедленно прервано и возобновлено на другом процессоре, для которого acquire никогда не выполнялся (и, следовательно, никогда не синхронизировался в соответствии с семантикой получения-выпуска)?

Например рассмотрим следующий код, который использует атомарность C ++ 11 и release-acquire упорядочение памяти для выполнения безблокировочной поточно-ориентированной инициализации:

if ( false == _initFlag.load(memory_order_acquire) ) {
_foo = ...; // initialize global
_bar = ...; // initialize global
... = ...; // initialize more globals
_initFlag.store(true, memory_order_release);
}
// use the initialized values ...

Если _initFlag.load(memory_order_acquire) возвращает true, тогда вызывающий поток будет знать, что инициализированные значения _foo, _barи т. д. … видимы (распространяются) на процессор на котором он в данный момент выполняется. Но что делать, если поток сразу же прерывается и перемещается на другой процессор? ..

Гарантирует ли стандарт C ++ 11, что новый процессор будет синхронизирован? Существуют ли какие-либо реализации или архитектуры, которые могут быть уязвимы для этого типа состояния гонки?

4

Решение

Возможно, что он будет выгружен и перенесен на другой процессор после получения, но, насколько мне известно, O / S должен обеспечить сохранение любого явного упорядочения памяти (это, вероятно, то, что он сохраняет в состояние потока). В противном случае было бы очень мало шансов на надежную работу в среде с несколькими процессорами.

Я думаю, что стандарт предполагает, что так и должно быть, на основании этого он должен.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]