Spinlock

Материал из Википедии — свободной энциклопедии

Перейти к: навигация, поиск

Спинлок (англ. Spinlock) — низкоуровневый примитив синхронизации, применяемый в многопроцессорных системах для реализации взаимного исключения.

Физически спинлок представляет собой переменную в памяти и реализуется на атомарных операциях, которые должны присутствовать в системе команд процессора. Каждый процессор, желающий получить доступ к разделяемому ресурсу, атомарно записывает условное значение «занято» в эту переменную, используя аналог операции swap (в архитектуре x86 — xchg). Если предыдущее значение переменной (возвращаемое командой) было «свободно» то считается, что данный процессор получил доступ к ресурсу, в противном случае, процессор возвращается к операции swap и крутится в цикле ожидая, пока спинлок будет освобождён. После работы с разделяемым ресурсом процессор-владелец спинлока должен записать в него условное значение «свободно».

Пример реализации спинлока на ассемблере x86:

mov eax, spinlock_address
mov ebx, SPINLOCK_BUSY
wait_cycle:
lock xchg [eax], ebx
cmp ebx, SPINLOCK_FREE
jnz wait_cycle
 
;<спинлок захвачен данным процессором, работа с разделяемым ресурсом>
 
mov eax, spinlock_address
mov ebx, SPINLOCK_FREE
lock xchg [eax], ebx

Более интеллектуальная реализация будет использовать обычную, а не атомарную операцию, для опроса в цикле, а атомарную операцию — только для попыток захвата. Дело в том, что реализация атомарных операций с памятью происходит путем аппаратного блокирования системной шины процессором на время выполнения атомарной операции (которая включает чтение, модификацию и запись). В течении выполнения этих трёх операций выполнение каких-либо других операций на шине невозможно, это снижает производительность других процессоров в системе (если они разделяют общую шину), даже если они не имеют никакого отношения к данному спинлоку.

Также используются т. н. queued spinlocks — «спинлоки с очередью». В них вместо присвоения 0 или 1 в атомарную переменную используется атомарное добавление структуры на голову списка, при том, что голова списка есть атомарная переменная типа «указатель».

Полезные свойства queued spinlockов:

  • гарантия порядка предоставления в порядке запроса, гарантия от «голоданий»
  • в цикле опроса каждый процессор опрашивает свою локальную переменную
  • ровно 1 атомарная операция при захвате и ровно 1 при освобождении

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

В пользовательских приложениях, работающий под управлением многозадачных ОС, использование спинлоков недопустимо, так как ожидание освобождения спинлока приводит к активному ожиданию в цикле, впустую расходующее вычислительные ресурсы процессора. Для синхронизации пользовательских программ должны применяться высокоуровневые примитивы, которые предполагают пассивное ожидание — если данная нить не может продолжить выполнение, то она отдаёт управление ОС, а не крутится в цикле ожидания спинлока (который потенциально может быть бесконечным).

Тем не менее спинлок с автоматическим наращиванием до захвата полноценного mutexа после истечения какого-то количества оборотов цикла применяется, например, в критических секциях Windows для оптимизации, заключающейся в отсутствии обращений к mutexу при отсутствии соревнования за ресурс.

[править] См. также

Источник — «http://ru.wikipedia.org/wiki/Spinlock»