Недавно я задал несколько вопросов об атомарности и C ++ 0x, и я хотел бы убедиться, что понимаю семантику упорядочения, прежде чем преобразовывать какой-либо код.Допустим, у нас есть код пре-0x:
atomic_int a = 0;
some_struct b;
Thread A:
b = something;
atomic_store_fence();
a = 1;
Thread B:
if( a == 1 )
{
atomic_load_fence();
proc(b);
}
Использование того, что предлагает вам текущий компилятор / платформа для atomic_int
, atomic_store_fence
и atomic_load_fence
.
В C ++ 0x код имеет несколько возможных форм.Два очевидных из них выглядят следующим образом:
atomic<int> a = ATOMIC_VAR_INIT(0);
some_struct b;
Thread A:
b = something;
atomic_thread_fence( memory_order_release );
a.store( 1, memory_order_relaxed );
Thread B:
if( a.load( memory_order_relaxed ) == 1)
{
atomic_thread_fence( memory_order_acquire );
proc(b);
}
или
Thread A:
b = something;
a.store( 1, memory_order_release );
Thread B:
if( a.load( memory_order_acquire ) == 1)
{
proc(b);
}
Правильно ли я прочитал, что атомарная последовательность освобождения / загрузки-получения представляет собой синхронизируется событие, которое имеет те же значения порядка памяти, что и явная версия забора?То есть, верна ли вторая версия?
Если верна, то вторая выдает забор больше, чем необходимо: даже когда a != 1
.Раздел 29.8-3 стандарта указывает, что я могу смешивать и сочетать атомные элементы и ограждения.Таким образом, является ли приведенная ниже корректная и разумная реализация?
Thread A:
b = something;
a.store( 1, memory_order_release );
Thread B:
if( a.load( memory_order_relaxed ) == 1 )
{
atomic_thread_fence( memory_order_acquire );
proc(b);
}