Действительно ли изменение является указателем, который рассматривают атомарным действием в C?

Как насчет https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/virtual-directory-setup-instructions

В этом случае ваш второе приложение стало другим приложением под основным.

31
задан Andrioid 18 May 2009 в 19:07
поделиться

7 ответов

Как уже упоминалось, в языке C нет ничего, что могло бы гарантировать это, и это зависит от вашей платформы.

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

Например, следующий код неисправен:

Поток A:

DoWork();
workDone = 1;

Поток B:

while(workDone != 0);

ReceiveResultsOfWork();

Хотя запись в workDone является атомарной, во многих системах процессор не гарантирует, что запись в workDone будет видна другим процессорам до записи, выполненной через DoWork ( ) видны. Компилятор также может свободно изменять порядок записи в workDone до вызова DoWork () . В обоих случаях, ReceiveResultsOfWork () может начать работать с неполными данными.

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

Или просто используйте блокировки. Гораздо проще, гораздо легче проверить правильность и в большинстве случаев более чем достаточно эффективный.

24
ответ дан 27 November 2019 в 22:24
поделиться

В языке C ничего не говорится о том, являются ли какие-либо операции атомарными. Я работал над микроконтроллерами с 8-битными шинами и 16-битными указателями; любая операция с указателем в этих системах потенциально была бы неатомарной. Я помню, как Intel 386 (некоторые из которых имели 16-битную шину) вызывал подобные опасения. Точно так же я могу представить себе системы с 64-битными процессорами, но с 32-битными шинами данных, которые могут вызвать аналогичные опасения по поводу операций с неатомарными указателями. (Я не проверял, существуют ли такие системы на самом деле.)

РЕДАКТИРОВАТЬ: Ответ Майкла стоит прочитать. Размер шины и размер указателя - не единственное соображение относительно атомарности; это был просто первый контрпример, который пришел мне в голову.

12
ответ дан 27 November 2019 в 22:24
поделиться

Вы не упомянули платформу. Поэтому я думаю, что несколько более точный вопрос будет:

Гарантируется ли атомарность изменений указателя?

Это различие необходимо, потому что разные реализации C / C ++ могут различаться в этом поведении. Определенная платформа может гарантировать атомарные назначения и при этом оставаться в рамках стандарта.

Относительно того, гарантируется ли это в целом в C / C ++, ответ - нет. Стандарт C не дает таких гарантий. Единственный способ гарантировать атомарное присвоение указателя - использовать механизм, специфичный для платформы, чтобы гарантировать атомарность присвоения. Например, эту гарантию предоставят методы Interlocked в Win32.

На какой платформе вы работаете?

5
ответ дан 27 November 2019 в 22:24
поделиться

Отказывающийся ответ заключается в том, что спецификация C не требует, чтобы присвоение указателя было атомарным, поэтому вы не можете рассчитывать на его атомарность.

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

4
ответ дан 27 November 2019 в 22:24
поделиться

«нормальная» модификация указателя не гарантируется атомарностью.

проверьте «Сравнить и поменять местами» (CAS) и другие атомарные операции, а не стандарт C, но большинство компиляторов имеют некоторые доступ к примитивам процессора. в случае GNU gcc есть несколько встроенных функций

3
ответ дан 27 November 2019 в 22:24
поделиться

Единственное, что гарантируется стандартом, - это тип sig_atomic_t.

Как вы видели из других ответов, это, вероятно, будет нормально при ориентации на общую архитектуру x86, но очень рискованно с большим количеством "специального" оборудования.

Если вы действительно отчаянно хотите знать, вы можете сравнить sizeof (sig_atomic_t) с sizeof (int *) и увидеть, какие они для вас целевые системы.

1
ответ дан 27 November 2019 в 22:24
поделиться

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

Благоразумная архитектура будет использовать блокировку.

1
ответ дан 27 November 2019 в 22:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: