C++ читает и записывает int Atomic?

У меня есть два потока: один обновляет int, а другой читает его. Это статистическое значение, при котором порядок чтения и записи не имеет значения.

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

Например, подумайте о значении = 0x0000FFFF, которое получает увеличенное значение 0x00010000.

Есть ли время, когда значение выглядит как 0x0001FFFF, о котором мне следует беспокоиться? Конечно, чем крупнее тип, тем больше вероятность того, что произойдет что-то подобное.

Я всегда синхронизировал эти типы доступа, но мне было любопытно, что думает сообщество.

Действительно? Мне было бы все равно, что думает сообщество. Мне было бы наплевать, каковы факты :)

sehe 28.09.2011 22:22

Интересное чтиво по теме: channel9.msdn.com/Shows/Going+Deep/…

ereOn 03.07.2013 13:01

Специально для =: stackoverflow.com/questions/8290768/…

Ciro Santilli TRUMP BAN IS BAD 16.06.2015 13:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
81
3
33 743
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

Нет, это не так (по крайней мере, вы не можете предположить, что это так). Сказав это, есть несколько уловок, чтобы сделать это атомарно, но они обычно не переносимы (см. Сравнить и обменять).

Да, вам нужно синхронизировать доступы. В C++ 0x это будет гонка данных и неопределенное поведение. С потоками POSIX это уже неопределенное поведение.

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

Вы должны синхронизировать, но на некоторых архитектурах есть эффективные способы сделать это.

Лучше всего использовать подпрограммы (возможно, замаскированные за макросами), чтобы можно было условно заменить реализации на специфичные для платформы.

В ядре Linux уже есть часть этого кода.

ЕСЛИ вы читаете / записываете 4-байтовое значение, И оно выровнено по DWORD в памяти, И вы работаете на архитектуре I32, ТО чтение и запись являются атомарными.

Где в руководствах разработчика программного обеспечения архитектуры Intel это сказано?

Daniel Trebbien 03.01.2011 19:56

@DanielTrebbien: возможно, см. stackoverflow.com/questions/5002046/…

sehe 28.09.2011 22:23

Мальчик, что за вопрос. Ответ на который:

Yes, no, hmmm, well, it depends

Все сводится к архитектуре системы. На IA32 правильно выровненный адрес будет атомарной операцией. Невыровненная запись может быть атомарной, это зависит от используемой системы кэширования. Если память находится в одной строке кэша L1, то она атомарна, в противном случае - нет. Ширина шины между ЦП и ОЗУ может повлиять на атомарный характер: правильно выровненная 16-битная запись на 8086 была атомарной, тогда как такая же запись на 8088 не была, потому что 8088 имел только 8-битную шину, тогда как 8086 имел 16-битная шина.

Кроме того, если вы используете C / C++, не забудьте пометить общее значение как изменчивое, иначе оптимизатор будет думать, что переменная никогда не обновляется в одном из ваших потоков.

Ключевое слово volatile бесполезно в многопоточных программах stackoverflow.com/questions/2484980/…

user152949 05.07.2012 16:13

@IngeHenriksen: Меня не убедила эта ссылка.

Skizz 05.07.2012 17:12

другой источник, но, к сожалению, очень старый (он предшествует std :: atomic): web.archive.org/web/20190219170904/https://software.intel.co‌ м /…

Max Barraclough 06.05.2020 00:43

Согласен со многими и особенно с Джейсон. В Windows можно было бы использовать InterlockedAdd и его друзей.

Ответ принят как подходящий

Сначала можно подумать, что чтение и запись размера машинной машины являются атомарными, но есть ряд проблем, которые необходимо решить, включая согласованность кеша между процессорами / ядрами. Используйте атомарные операции, такие как Interlocked * в Windows и аналогичные в Linux. C++ 0x будет иметь «атомарный» шаблон, чтобы обернуть их в красивый и кроссплатформенный интерфейс. На данный момент, если вы используете уровень абстракции платформы, он может предоставлять эти функции. ТУЗ делает, см. Шаблон класса ACE_Atomic_Op.

Документ ACE_Atomic_Op перемещен - теперь его можно найти по адресу dre.vanderbilt.edu/~schmidt/DOC_ROOT/ACE/ace/Atomic_Op.inl

Byron 09.12.2011 20:41

Чтобы повторить то, что все говорили наверху, язык, предшествующий C++ 0x, не может ничего гарантировать в отношении доступа к общей памяти из нескольких потоков. Любые гарантии будут зависеть от компилятора.

Помимо проблемы с кешем, упомянутой выше ...

Если вы перенесете код на процессор с меньшим размером регистра, он больше не будет атомарным.

ИМО, проблемы с потоками слишком сложны, чтобы рисковать.

В Windows Interlocked *** Exchange *** Add гарантированно будет атомарным.

Единственный переносимый способ - использовать тип sig_atomic_t, определенный в заголовке signal.h для вашего компилятора. В большинстве реализаций C и C++ это int. Затем объявите вашу переменную как «volatile sig_atomic_t».

volatile не делает то, что вы думаете stackoverflow.com/questions/2484980/…

Sam Miller 08.07.2010 06:48

Возьмем этот пример

int x;
x++;
x=x+5;

Предполагается, что первый оператор является атомарным, поскольку он преобразуется в одну директиву сборки INC, которая занимает один цикл ЦП. Однако второе присваивание требует нескольких операций, так что это явно не атомарная операция.

Другой, например,

x=5;

Опять же, вам нужно дизассемблировать код, чтобы увидеть, что именно здесь происходит.

Но компилятор мог оптимизировать его до x+=6.

tc. 13.08.2010 18:02

tc, Я думаю, что в тот момент, когда вы используете константу (например, 6), инструкция не будет выполнена за один машинный цикл. Попытайтесь увидеть набор инструкций x + = 6 по сравнению с x ++

Некоторые люди думают, что ++ c является атомарным, но следят за созданной сборкой. Например, с 'gcc -S':

movl    cpt.1586(%rip), %eax
addl    , %eax
movl    %eax, cpt.1586(%rip)

Чтобы увеличить int, компилятор сначала загружает его в регистр и сохраняет обратно в память. Это не атомарно.

Это не проблема, если в переменную записывает только один поток, поскольку разрывов нет.

Ben Voigt 18.04.2012 02:40

Однозначно НЕТ! Этот ответ от нашего высшего авторитета в области C++, М. Boost:
Не гарантируется, что операции с «обычными» переменными будут атомарными.

эта ссылка говорит только о том, что операция arithmetic, которая состоит из последовательности чтения-обновления-записи для «обычных» переменных, не является атомарной, а не является ли операция read или write для «обычных» переменных атомарной или нет.

D3Hunter 24.02.2018 10:48

Другие вопросы по теме