|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
|||||||||||
Как правильно получать значение interlocked переменной?21.02.2021, 21:42. Показов 8487. Ответов 35
Всем привет!
Как правильно получать значение interlocked переменной ??? "interlocked value" - это по другому атомарное значение. Начиная с с++ можно использовать std::atomic Но если, допустим, у вас слишком старый компилятор, то можно воспользоваться interlocked-функциями из WINAPI На офф. сайте есть пример использования. А так разве вообще можно делать? Код на офф. сайте содержит баг? Переменная модифицируется и читается одновременно из разных потоков:
Но чтение то переменной ничем не защищенно! Получается, что код на офф. сайте содержит UB. А как правильно получать значение interlocked переменной? Среди списка имеющихся функций я так и не нашла такую, которая просто возвращает значение переменной. Стек-оверфлоу предлагает какие то костыли по принципу:
Я хочу просто получить значение атомарной переменной. При этом я не хочу модифицировать саму эту переменную! Может быть есть какая то InterlockedExchangeGet ?
0
|
|||||||||||
| 21.02.2021, 21:42 | |
|
Ответы с готовыми решениями:
35
Как записать и получать значение переменной в другом классе Как правильно добавить значение переменной к ссылке? Как правильно выстроить это выражение , чтобы получить значение переменной x ? |
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
|||
| 23.02.2021, 02:02 | |||
Сообщение было отмечено eva2326 как решение
Решениеvolatile для stop и test, иначе это будет соптимизировано, т.к.
1
|
|||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
|||||||||||||||||||||||||||||||||||||
| 23.02.2021, 03:25 [ТС] | |||||||||||||||||||||||||||||||||||||
|
Тест не-атомарности:
Похоже, что потоки просто не успевали стартовать. Я вставила паузу, и вроде бы стабильно заработало. Добавлено через 1 час 17 минут Сейчас это выглядит как голословное утверждение. Сколько здесь независимых групп?
Например выражения:
b, a уже полностью вычислено, и все связанные с ним сайд эффекты уже завершены.Вот такой перестановки быть не может:
В частности, аппаратура может закладываться на порядок вычисления a и b. Результат не может быть упорядочен или не упорядочен. Он просто есть. Упорядоченным (или не упорядоченным) может быть сам алгоритм, который к этому результату привел. Если процессор начнет переставлять инструкции как ему вздумается, тогда алгоритм будет коверкаться. И тогда, вместо корректного ожидаемого результата вы получите UB. В реальности этого не происходит. Значит в реальности процессор не может переставлять инструкции как ему вздумается. Значит в реальности перестановки ограниченны. Ограничены чем? В особенности интересует "магическое переупорядочивание". Термины нужны, что бы избежать неоднозначностей при описании явлений данной предметной области. Если "общая память" - это действительно термин, а не ваша выдумка, тогда он должен быть где-то описан, и иметь четкое определение. Предоставьте ссылку на первоисточник. Инкремент существует, потому что он нужен алгоритму для решения задачи. Факт его существования вообще никак не связан с синхронизациями. И не имеет ни малейшего отношения к моему вопросу. Мой вопрос был: зачем нужна какая то синхронизация для атомарных операций? Ведь они итак уже атомарны. Я получила ответ на свой вопрос: И тогда на помощь приходит Interlocked API. Оно позволяет запускать сложные многоступенчатые процедуры как атомарные. То есть, атомарными они на самом деле не являются. Но Interlocked API умеет имитировать "атомарность" за счет использования хитроумной синхронизации. Эта синхронизация, по всей видимости, использует хитроумные lock free, хотя это не гарантируется. И вот, что бы люди понимали, что деда мороза не существует, разработчики честно предупреждают: "мы используем синхронизацию". Атомарные операции не нуждаются в синхронизации, потому что они атомарные! И не имеют ни малейшего отношения к неатомарным операциям.
0
|
|||||||||||||||||||||||||||||||||||||
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
|||||||||||||||||
| 23.02.2021, 06:52 | |||||||||||||||||
|
Кликните здесь для просмотра всего текста
Представим условный shared_ptr, который инкрементирует и декрементирует с relaxed ordering который хранит указатель на что-то И есть у нас два потока, у каждого своя копия shared_ptr c объектом. Счетчик ссылок равен двум. И вот в первом потоке вызывается деструктор shared_ptr. Последовательность действий деструктора такая: 1) атомарный декремент счетчика 2) если возвращенное значение 1 (последняя ссылка), то 3) чтение значения своего указателя в регистр 4) вызов деструктора объекта и деаллокация памяти по этому значению и т.д. Только вот атомарный декремент и проверка условия не быстрая операция, а предсказатель ветвлений может выполнить пункт 3) ещё до завершения 1) и 2). Это простое чтение в регистр, которое никак не зависит от первых двух. И вот не успел завершится 1), присходит переключение контекста потока. Второй поток в это время вызывает reset() у shared_ptr, и записывает новое значение указателя, потом вызывается деструктор, успешно выполняется этап 1), счетчик вернул 2, ничего не делаем. Далее просыпается первый поток, выполняет первую операцию, счетчик ссылок вернул один, можем выполнять этап 4), значение в регистр уже загружено, только это значение, которое уже обработал второй поток, а сам записал новое. Получим вызов деструктора уже убитого объекта и деаллокацию по невалидному адресу. А вот если у декремента был бы aсquire барьер, то это запретило бы переупорядочивать операцию чтения, а этап 3 выполнялся бы только после завершения атомарной операции. Инкремент синхронизировать не с чем (у нашего shared_ptr только один счетчик ссылок, без weak_ptr) У меня под рукой только gnu c++ библиотека, выкладывать кучу библиотечного кода и объяснять(разбираться в нём самому) неохота, но вот две основные атомарные операции для счетчиков (и use и weak): Кликните здесь для просмотра всего текста
Вы это вопрос инженерам задайте, которые чипы проектируют. Вот пример алгоритма. https://en.wikipedia.org/wiki/Tomasulo_algorithm Где там сайд эфекты? Даже если они там есть, то до тех пор, пока вы в своём коде явно не закладываетесь на них, компилятор может оптимизировать этот код как угодно. В рамках одного потока, если у вас дальше есть операция c = a + b (или использует сайд эффекты вычисления a и b), то вот она не будет переупорядочена с этими двумя. (см. In hardware) И вот тут(см. главу 2, да ивообще почитайте, очень интересно)https://www.cl.cam.ac.uk/~pes2... /test7.pdf Вот в стандарте про синхронизацию http://eel.is/c++draft/intro.m... ro.races-3 И далее, где она используется для межпоточного упорядочивания.
1
|
|||||||||||||||||
|
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,137
|
||
| 23.02.2021, 10:37 | ||
|
Можно ещё другой тест. Один поток по очереди пишет 0 и -1 в переменную, а в main читаем и проверяем атомарность. Аналогично предыдущему варианту у меня неатомарность проявляется только для debug версии.
1
|
||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||||||
| 23.02.2021, 16:40 [ТС] | ||||||||||
|
Если вкратце: гарантии с++ исполняются. Как я и писала выше: ни компилятор, ни процессор не смогут переупорядочить выражения, которые имеют побочные эффекты. Но тогда получается, что вот здесь - баг компилятора Или есть какая то оговорка насчет глобальных переменных? Чтение/запись волатильных переменных = побочный эффект. Я уже давала вам ссылку на офф. сайт, где черным по белому описаны правила вычислений выражений. К моменту начала вычисления выражения b, все побочные эффекты выражения a уже должны быть завершены.И компилятор со всеми своими оптимизациями не имеет права нарушать этот контракт. Вы мне напомнили один анекдот про программистов.
Из того факта, что грамотное применение синхронизации позволяет написать более эффективный код, никак не следует, что синхронизация нужна конкретно атомарным операциям. Атомарные операции не нуждаются ни в какой синхронизации, и прекрасно могут обойтись и без неё. Дальнейшие ваши ответы я никак не комментирую, потому что это не ответы, а какая то бесполезная чушь.
0
|
||||||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
|
| 23.02.2021, 16:59 [ТС] | |
|
0
|
|
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
||||||||
| 23.02.2021, 17:29 | ||||||||
|
0
|
||||||||
|
2737 / 894 / 331
Регистрация: 10.02.2018
Сообщений: 2,137
|
||||||||||||
| 23.02.2021, 17:54 | ||||||||||||
ассемблерный код
1
|
||||||||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||||||||||||||
| 10.03.2021, 19:05 [ТС] | ||||||||||||||||||
Такое впечатление, что вы спутали название "Библиотеки атомарных операций" с собственно "атомарными операциями". Из того факта, что "Библиотека атомарных операций" предоставляет доступ к барьерам памяти, никак не следует, что атомарные операции являются синхронизирующими. Сам std::atomic вообще не является примитивом синхронизации.
Но это не делает сам std::atomic примитивом синхронизации. И не является его основным предназначением. И не имеет никакого отношения к собственно "атомарным операциям". Добавлено через 3 минуты Вы мне пишите, якобы атомики нужны что бы синхронизировать неатомарный код. Бред жеж. Добавлено через 1 минуту
0
|
||||||||||||||||||
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
||||||||||
| 10.03.2021, 19:47 | ||||||||||
|
1) где начинается lifetime объекта, на который указывает test? 2) согласно стандарту объект, на который указывает test - не атомарный и доступ к нему из разных потоков не синхронизирован, поэтому UB Кликните здесь для просмотра всего текста
в частности, вод код - сгенерированный gcc 10.2
)eva2326, вы вроде взрослый и грамотный человек и программист. Я, например, не знаю и не понимаю многих вещей, но когда мне начинают объяснять я не скалю зубы (типа, "я не понимаю, поэтому вы несёте какую-то чушь"), а стараюсь самостоятельно разобраться. Т.к. не знать или не понимать - это нормально. Возьмите книгу Уильямса, например. Там целая глава посвящена атомарным операциям, постарайтесь разобраться, что они и для чего(вы то уж точно сможете).
0
|
||||||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||
| 10.03.2021, 20:35 [ТС] | ||||||
|
Насколько мне известно, стандарт такие вещи не регламентирует. Нужно смотреть на гарантии, которые предоставляют конкретные платформы: раз и два Они вообще не используют никакой синхронизации. Вы "атомарное чтение" с "барьером памяти" не перепутали? Я уже получила все ответы на все вопросы данной темы. Если вкратце: чтение/запись выровненных волатильных интов действительно атомарно.
0
|
||||||
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
||||||
| 10.03.2021, 21:01 | ||||||
|
Атомарные операции регламентированы. И что вы тогда подразумевали под багом компилятора? ![]() Не используют, а предоставляют(или не предоставляют)! Использовать её должен ваш код!
0
|
||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
|||||||||||
| 10.03.2021, 21:49 [ТС] | |||||||||||
|
Вы никогда не думали, почему атомарные объекты называют атомарными? Компилятор оптимизировал чтение глобальной переменной. Но разве компилятор имеет право делать такую оптимизацию? Глобальные переменные, так же, как и волатильные, могут иметь побочные эффекты, источник которых может быть невидим для компилятора. И тем не менее, компилятор должен учитывать, что переменная может неожиданно изменить своё значение. Для волатительных переменных компилятор действительно это учитывает, и не делает потенциально губительных оптимизаций. А для обычных глобальных, он почему то думает, что на дворе 98, и треды в с++ ещё не завезли. Синхронизацию предоставляют всякие мутексы/барьеры, которые вообще ортогональны атомикам.
И как именно её может использовать мой код? Проиллюстрируйте на практике. Сейчас внезапно выяснится, что это просто атомарное чтение. В #8 я задала вопрос, на который получила исчерпывающий ответ
0
|
|||||||||||
|
6354 / 3525 / 1428
Регистрация: 07.02.2019
Сообщений: 9,008
|
|||||
| 10.03.2021, 22:40 | |||||
|
(обратите внимание на примечания в конце). Правила и поведение этой машины в многопоточном контексте описаны тут. Ваш код эти правила не соблюдает. В рамках однопоточного кода (на поведение которого вы и опираетесь со своими "точками следования", которых в с++11 давно нет) эти оптимизации не нарушают program order. Инач говоря, наблюдаемое поведение вашего кода не нарушается.
0
|
|||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||
| 11.03.2021, 00:10 [ТС] | ||||||
|
Просто любопытно: как вообще вы могли так подумать, учитывая, что исходный посыл диаметрально противоположный? Там написано, что атомарные операции уже итак атомарные сами по себе, и никакая синхронизация им не нужна. Однако, aтомарность гарантируется только для каких то простейших действий. А если нужно что-то посложнее, тогда нужно использовать синхронизацию. Он показывает суть: просто берете, и читаете данные из переменной. Не нужны никакие синхронизации. Никаких там барьеров или мутексов. Вы просто осуществляете доступ к переменной без какой либо дополнительной защиты. --- В том, что касается реального многопоточного кода... Сейчас сложилось очень нехорошее впечатление о вас. Вы вроде бы присутствуете в моей теме, но при этом совершенно не вникаете, и не понимаете о чем она. Или как ещё можно объяснить тот факт, что реальный пример многопоточного кода я привела ещё в стартопике. И именно вокруг этого примера крутится вся эта тема. Этот пример кода уже тщательно рассмотрен и проанализирован. Все необходимые нормативные документы уже прочитаны. Ответы на вопросы уже получены. Тесты написаны. И саму эту тему, уже можно закрывать. И тут вы, внезапно, просите показать реальный пример многопоточного кода.
0
|
||||||
| 11.03.2021, 00:52 | ||||
|
Не по теме:
Вместо того, что бы говорить, что я несу чушь, могли бы просто сказать, что вам это не нужно и не интересно и ничего вы синхронизировать не собираетесь в своём коде. Я бы прошел мимо. Постараюсь вас больше не беспокоить
0
|
||||
| 11.03.2021, 00:52 | |
|
Как при срабатывании SIGINT правильно передать значение переменной i в функцию closing
Как правильно получать POST данные в обрабочтике ? [React] Как правильно получать components с сервера? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/
TL DR
Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js.
В помощники взял Яндекс-Алису.
Было создано три зала на разные интересы.
исторические и ретро
сериал Хичкок. . .
|
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|