Есть ли функции для выполнения атомарных операций (как инкремент / декремент целого числа) и т.д. поддерживаются библиотекой Времени выполнения C или какими-либо другими служебными библиотеками?
Если да, что все операции могут быть сделаны атомарным использованием таких функций?
Будет более выгодно использовать такие функции, чем нормальные примитивы синхронизации как взаимное исключение и т.д.?
ОС: Windows, Linux, Solaris & VxWorks
В библиотеке C их нет.
В Linux gcc предоставляет некоторые возможности - ищите __ sync_fetch_and_add
, __ sync_fetch_and_sub
и так далее.
В случае Windows найдите InterlockedIncrement
, InterlockedDecrement``,
InterlockedExchange` и т. Д. Если вы используете gcc в Windows, я предполагаю, что он также имеет те же встроенные модули, что и в Linux (хотя я не проверял это).
В Solaris это будет зависеть. Предположительно, если вы используете gcc, он, вероятно, (снова) будет иметь те же встроенные модули, что и в Linux.В остальном есть библиотеки, но ничего стандартизированного.
C11 добавил (разумно) полный набор атомарных операций и атомарных типов. Операции включают в себя такие вещи, как atomic_fetch_add
и atomic_fetch_sum
(и * _ явные
версии того же самого, которые позволяют указать нужную модель упорядочения, где по умолчанию всегда используется memory_order_seq_cst
). Существуют также функции ограждения
, такие как atomic_thread_fence
и atomic_signal_fence
.
Типы соответствуют каждому из нормальных целочисленных типов - например, atomic_int8_t
соответствует int8_t
и atomic_uint_least64_t
соответствует uint_least64_t
]. Это имена typedef
, определенные в
. Чтобы избежать конфликтов с любыми существующими именами, вы можете опустить заголовок; сам компилятор использует имена в пространстве имен разработчика (например, _Atomic_uint_least32_t
вместо atomic_uint_least32_t
).
"Выгодно" - это ситуативно. Всегда эффективность зависит от обстоятельств. Вы можете ожидать, что произойдет что-то замечательное, когда вы замените мьютекс на что-то вроде этого, но вы можете не получить никакой выгоды (если это не такой популярный случай) или ухудшить ситуацию (если вы случайно создадите 'spin-lock').
На всех поддерживаемых платформах вы можете использовать атомарные операции GLib . На платформах, которые имеют встроенные атомарные операции (например, инструкции по сборке), glib будет их использовать. На других платформах он вернется к использованию мьютексов.
Я думаю, что атомарные операции могут дать вам прирост скорости, даже если мьютексы реализуются с их помощью. С мьютексом у вас будет как минимум две атомарных операции (блокировка и разблокировка) плюс фактическая операция. Если доступна атомарная операция, это единственная операция.
Не понимаю, что вы имеете в виду под библиотекой времени выполнения C. Собственно язык или стандартная библиотека не предоставляют никаких средств для этого. Вам нужно будет использовать библиотеку / API для конкретной ОС. Также не дайте себя обмануть sig_atomic_t
- они не такие, как кажется на первый взгляд, и полезны только в контексте обработчиков сигналов.
В Windows есть InterlockedExchange и подобные. Для Linux вы можете взять атомарные макросы glibc - они переносимы (см. i486 atomic.h ). Я не знаю решения для других операционных систем.
В общем, вы можете использовать инструкцию xchg
на x86 для атомарных операций (работает и на двухъядерных процессорах).
Что касается вашего второго вопроса, нет, я не думаю, что использование атомарных операций будет быстрее, чем использование мьютексов. Например, библиотека pthreads уже реализует мьютексы с атомарными операциями, что очень быстро.