Поделиться через


Доступ к заблокированным переменным

Приложения должны синхронизировать доступ к переменным, совместно используемым несколькими потоками. Приложения также должны гарантировать, что операции с этими переменными выполняются атомарно (выполняются полностью или вообще не выполняются).

Простые операции чтения и записи в правильно выровненные 32-разрядные переменные являются атомарными операциями. Другими словами, вы не будете обновлять только одну часть переменной; все биты обновляются атомарным образом. Однако синхронизация доступа не гарантируется. Если два потока считывают и записывают данные из одной переменной, невозможно определить, будет ли один поток выполнять операцию чтения до того, как другой выполнит свою операцию записи.

Простые операции чтения и записи в правильно выровненные 64-разрядные переменные являются атомарными в 64-разрядной версии Windows. Операции чтения и записи в 64-разрядные значения не гарантированно будут атомарными в 32-разрядной версии Windows. Операции чтения и записи в переменные других размеров не гарантируют атомарности на любой платформе.

The Interlocked API

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

Функции InterlockedIncrement и InterlockedDecrement объединяют шаги, связанные с увеличением или уменьшением переменной в атомарную операцию. Эта функция полезна в многозадачности операционной системы, в которой система может прерывать выполнение одного потока, чтобы предоставить кусок процессорного времени другому потоку. Без такой синхронизации два потока могут считывать одно и то же значение, увеличивать его на 1 и сохранять новое значение для общего увеличения 1 вместо 2. Заблокированные функции доступа к переменным защищают от такого рода ошибок.

Функции InterlockedExchange и InterlockedExchangePointer атомарно обмениваются значениями указанных переменных. Функция InterlockedExchangeAdd объединяет две операции: добавление двух переменных вместе и сохранение результата в одной из переменных.

Функции InterlockedCompareExchange, InterlockedCompare64Exchange128 и InterlockedCompareExchangePointer объединяют две операции: сравнение двух значений и сохранение третьего значения в одной из переменных на основе результата сравнения.

Функции InterlockedAnd, InterlockedOr и InterlockedXor атомарно выполняют операции AND, OR и XOR соответственно.

Существуют функции, специально предназначенные для выполнения взаимоблокированного доступа к переменным для 64-разрядных значений памяти и адресов и оптимизированные для использования в 64-разрядной версии Windows. Каждая из этих функций содержит "64" в имени; Например, InterlockedDecrement64 и InterlockedCompareExchangeAcquire64.

Большинство взаимосвязанных функций обеспечивают барьеры полной памяти на всех платформах Windows. Существуют также функции, объединяющие основные операции доступа к заблокированным переменным с семантикой упорядочения памяти, поддерживаемой определенными процессорами. Каждая из этих функций содержит слово "Acquire" или "Release" в своих именах; например InterlockedDecrementAcquire и InterlockedDecrementRelease. Семантика получения памяти указывает, что операция памяти, выполняемая текущим потоком, будет видна перед попыткой выполнения любых других операций с памятью. Семантика памяти выпуска указывает, что операция памяти, выполняемая текущим потоком, будет видна после завершения всех остальных операций с памятью. Эта семантика позволяет принудительно выполнять операции памяти в определенном порядке. Используйте семантику получения при вводе защищенной области и семантику освобождения при выходе из нее.

Встроенные инструкции компилятора

Проблемы синхронизации и многопроцессорности