2015-01-06 3 views
1

Я сталкивался с некоторыми проблемами с моим атомным контейнером и увидел this link.C++ 11 Безопасность потока std :: atomic <T> копирующие конструкторы

Есть ли причина, по которой std :: atomic не копируется? Решение кажется this, где они просто передают значение T неатомному конструктору с функцией атомной нагрузки (если я не ошибаюсь).

Так что, в общем, эта версия конструктора конвейера безопасна?

template<typename T> 
struct MobileAtomic 
{ 
    std::atomic<T> atomic; 

    explicit MobileAtomic(std::atomic<T> const& a) : atomic(a.load()) {} 

}; 
+0

Непонятно, достигает ли этот код ничего разумного. Atomics служат очень специфической цели, и, как правило, нет смысла копировать их. –

+1

Как аналог: атомный int намного ближе к мьютезу или семафору, чем к целому. Вы можете запросить текущее состояние семафора (что соответствует атомной нагрузке), но нет смысла копировать сам семафор. Это механизм синхронизации и создание копии, если это неразумно. –

+2

Мне также непонятно, что это означает, что «конструктор будет потокобезопасным». Кто строит то, что по-другому? –

ответ

4

Есть причина, почему станд :: атомное не копировать-constructable?

Да.

Когда вы просите создать конструкцию atomic, вы просите «нормальные» правила однопоточной последовательной согласованности применять к переменной, которая не соответствует этим правилам.

В сущности, обобщенного решения нет.

Используя конструктор, который вы показываете в вопросе, вы жертвуете детерминированным результатом, поскольку у вас нет гарантии, что исходный и целевой объекты будут эквивалентны после завершения строительства.

+0

Кажется, у меня есть только два варианта: я могу только вернуть значение атомной переменной по значению (которое может измениться другим потоком до тех пор, пока значение не будет присвоено вызовом = гонка) или не вернет ссылку на атомную переменную (который является переменной, которую я не хочу раскрывать). Я думаю, мой лучший вариант - вернуть ссылку на const, которую я еще не пробовал. – JohnJohn

+0

@JohnJohn Другой вариант - заблокировать переменную с помощью мьютекса на время чтения. –

+1

@JohnJohn: Вы можете не осознавать этого, но **, как только вы сделаете копию **, значение исходного объекта может расходиться со значением копии. это не состояние гонки. Это нормальное поведение, когда у вас есть две переменные. Если вы логически имеете одно значение, у вас должен быть один объект. – MSalters