Здравствуйте, vdimas, Вы писали:
V>>>·>т.к. такое его использование — data race, а значит ub. Использование std::atomic не является data race.
V>>>1. Data race не всегда UB, часто так и задумано.
V>·>Всегда.
V>·>Не путай data race и race condition.
V>Давай разбираться, кто путает:
В этом разбираться не надо. Надо разобраться что ты напутал.
If a data race occurs, the behavior of the program is undefined.
А вот race condition действительно относится к семантике и может быть "так и задумано".
V>>>2. Использование std::atomic, защищает от data race неатомарные типы, для специализаций под эти типы структура std::atomic содержит внутри себя мьютекс.
V>>>Что характерно, что для таких типов memory_order не играет никакого значения, т.к. оперирование примитивами синхронизации означает выполнение самых строгих гарантий, т.е. обсуждаемый memory_order актуален только для типов, которые проц умеет сохранять/читать атомарно.
V>·>Опять фантазируешь.
V>Тут лучше не выдумывать из головы, а внимать.
V>Ценной информацией делюсь, ваще-то.
V>Например, насчёт выделенного.
Об этом я тут рассказывал где-то неделю назад.
V>·>Мьютекс содержат только те std::atomic, которые данная имплементация языка не может защитить от data race без мьютекса.
V>Data race в случае memory_order_release происходит в полный рост для атомарных типов.
V>При некоторых других комбинациях (на стороне записи и чтения) — тоже аж бегом.
Нет. std::atomic гарантирует отсутсвие data race:
"A program that has two conflicting evaluations has a data race unless ... both conflicting evaluations are atomic operations (see std::atomic) ..."
Без всяких оговорок о конкретном memory_order или о том, какими типами они специализированы.
V>·>И это можно даже проверить для каждого конкретного случая, см. метод is_lock_free().
V>Проверить-то можно, но не то, что ты формулируешь словами.
Я цитирую стандарт.
V>·>Важно. Т.к. в этом случае корректность кода обеспечивается языком и операционкой. Прямой вызов хендлера в описанной тобой ситуации — ошибка программиста, баг в программе.
V>Интересная заява. ))
V>И как ты собрался её подтверждать, мне уже любопытно?
По-моему это настолько очевидно, что я даже не понимаю что здесь требуется подтверждать. Тот факт, что мы передали указатель на функцию куда-то, это ещё не означает, что эту функцию стало безопасно дёргать из многопоточки.
V>>>·>В этом случае сработают соответсвующие механизмы atomic.
V>>>А как до атомик-то жили? ))
V>·>Я ж отвечал уже — платформено-зависимыми функциями — ассемблерные вставки, сисколлы.
V>Для однопроцессорных мультизадачных операционок никаких дополнительных приседаний в виде ассемблерных вставок не требовалось.
В смысле "у меня всё работало"?
Отличный аргумент.
V>>>Т.е. обработчики сигнала могут работать конкурентно
V>·>Не могут. Опять фантазии, явно противоречащие спекам:
V>·>Signals generated for a process are delivered to only one thread. Thus, if more than one thread is eligible to receive a signal, one has to be chosen.
V>·>(c) http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_04_02
V>А смысл цитировать некие частности после моего:
V>V>В зависимости от реализации POSIX, даже в зависимости от версий Linux, по приходу сигнала поведение было и есть разное.
V>Некоторые сигналы вызываются первым попашимся потоком, который не замаскировал этот сигнал.
V>Некоторые сигналы вызывались у всех потоков, порождённых данным процессом.
V>Некоторые сигналы (напр. переполнение с плавающей точкой) вызываются у конкретного потока, в котором произошла ошибка.
V>Сверху еще посылка сигналов конкретным потокам через либу pthread.
И что? Ничто из этого не означает, что обработчик сигнала можно вызывать из треда напрямую. Ядро ответственно за корректную синхронизацию вызовов хендлеров.
V>·>Т.е. операционка следит за тем, чтобы сигналы процессу шли последовательно.
V>И опять не понимаю, зачем ты насасываешь из пальца столь громкие утверждения?
_Посылаться_ они могут конкруентно, да. А ты утверждаешь, что обработчик сигнала может дёргаться конкурентно. Сигналы вызываются асинхронно, а не конкурентно.