Является ли инициализация атомарного указателя атомарным? Что произойдет, если при инициализации или выделении памяти возникнет ошибка? - PullRequest
0 голосов
/ 14 мая 2018

Если я объявляю и определяю атомарный указатель за один раз, как -

std::atomic<int*> iptr = new int(1);    
std::atomic<T*> iptr = new T();

Как я понимаю, вся операция не атомарна.

new T () включает в себя назначение памяти, конструирование объекта T, а затем он будет атомарно назначен iptr. T может быть тривиально конструируемым, и в этом случае построение T не должно генерировать, но некоторые пользовательские T могут бросать.

Что если между конструкцией T или выделением памяти какой-то другой поток использует iptr?

Эта операция действительно атомарна? Одним из способов сделать его атомарным является нарушение декларации и определения, например,

T* temp = new T();
std::atomic<T*> iptr = temp;    

Есть ли другой способ сделать то же самое атомно? Мое понимание неверно?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Создание нового безымянного объекта не является атомарным, но это не обязательно.[Как указано выше, любое исключение будет просто влиять на время жизни временного объекта, созданного до того, как он будет назначен атомарному элементу, и должно очищаться нормально.]

Назначение этого временного указателя на ваш атомарный указательявляется атомарным.

Моя большая проблема в том, что в настоящее время ваш код не может определить, выполнил ли другой поток назначение, поэтому вам придется рассмотреть возможность использования testandset или swap.Тогда у вас возникают проблемы с неудачной проверкой / обменом, и у вас есть временный указатель на объект, который вам больше не нужен.

Если вы используете локальную переменную (а не безымянную временную), вы получаетешанс убрать это.

Если вы используете умный указатель для атомарного и временного, он самоуничтожится.

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

0 голосов
/ 14 мая 2018

new T() включает в себя назначение памяти,

Да.

создание объекта T

Да.

и тогда он будет атомарно назначен iptr.

Точно (почти, это адрес объекта, который используется здесь).Он используется для инициализации атомарного после выделения памяти и построения.

T может быть тривиально конструируемым, и в этом случае конструирование T не должно вызывать, но какой-то пользовательопределены T МОЖЕТ бросить.

И если это произойдет, инициализация атома не будет достигнута.Выражение new не пропускает память, если c'tor выбрасывает, оно вызывает правильную функцию deallcoation.Так что ваше временное и прямое использование нового выражения имеет точно такую ​​же семантику.

...