Шрифт:
Для примеров использования условных переменных смотрите файлы
BKL: Большая блокировка ядра
Добро пожаловать к "рыжему пасынку" ядра. Большая блокировка ядра (Big Kernel Lock, BKL) — это глобальная спин-блокировка, которая была создана специально для того, чтобы облегчить переход от первоначальной реализации SMP в операционной системе Linux к мелкоструктурным блокировкам. Блокировка BKL имеет следующие интересные свойства.
• Во время удержания BKL можно переходить в состояние ожидания. Блокировка автоматически освобождается, когда задание переходит в состояние ожидания, и снова захватывается, когда задание планируется на выполнение. Конечно, это не означает, что безопасно переходить в состояние ожидания при удержании BKL, просто это можно делать и это не приведет к взаимоблокировке.
• Блокировка BKL рекурсивна. Один процесс может захватывать эту блокировку несколько раз подряд, и это не приведет к самоблокировке, как в случае обычных спин-блокировок.
• Блокировка BKL может использоваться только в контексте процесса.
• Блокировка BKL — это от лукавого.
Рассмотренные свойства дали возможность упростить переход от ядер серии 2.0 к серии 2.2. Когда в ядро 2.0 была введена поддержка SMP, только одно задание могло выполняться в режиме ядра в любой момент времени (конечно, сейчас ядро распараллелено очень хорошо — пройден огромный путь). Целью создания ядра серии 2.2 было обеспечение возможности параллельного выполнения кода ядра на нескольких процессорах. Блокировка BKL была введена для того, чтобы упростить переход к мелкоструктурным блокировкам. В те времена она оказала большую помощь, а сегодня она приводит к ухудшению масштабируемости [51] .
51
Хотя, может быть, она и не такая страшная, какой ее иногда пытаются представить, вес же некоторые люди считают ее "воплощением дьявола" в ядре.
Использовать блокировку BKL не рекомендуется. На самом деле, новый код никогда не должен использовать BKL. Однако эта блокировка все еще достаточно интенсивно используется в некоторых частях ядра. Поэтому важно понимать особенности большой блокировки ядра и интерфейса к ней. Блокировка BKL ведет себя, как обычная спин-блокировка, за исключением тех особенностей, которые были рассмотрены выше. Функция
Когда эта блокировка захвачена, происходит запрещение преемптивности. Для ядер, скомпилированных под однопроцессорную машину, код BKL на самом деле не выполняет никаких блокировок. В табл. 9.8 приведен полный список функций работы с BKL.
Таблица 9.8. Функции работы с большой блокировкой ядра
Функция | Описание |
---|---|
lock_kernel | Захватить блокировку BKL |
unlock_kernel | Освободить блокировку BKL |
kernel_locked | Возвратить ненулевое значение, если блокировка захвачена, и нуль- в противном случае |
Одна из самых главных проблем, связанных с большой блокировкой ядра, — как определить, что защищается с помощью данной блокировки. Часто блокировка BKL ассоциируется с кодом (например, она "синхронизирует вызовы функции
Секвентные блокировки
Секвентная блокировка (seq lock) — это новый тип блокировки, который появился в ядрах серии 2.6. Эти блокировки предоставляют очень простой механизм чтения и записи совместно используемых данных. Работа таких блокировок основана на счетчике последовательности событий. Перед записью рассматриваемых данных захватывается спин-блокировка, и значение счетчика увеличивается на единицу. После записи данных значение счетчика снова увеличивается на единицу, и спин-блокировка освобождается, давая возможность записи другим потокам. Перед чтением и после чтения данных проверяется значение счетчика. Если два полученных значения одинаковы, то во время чтения данных новый акт записи не начинался, Если к тому же оба эти значения четные, то к моменту начала чтения акт записи был закончен (при захвате блокировки на запись значение счетчика становится нечетным, а перед освобождением — снова четным, так как изначальное значение счетчика равно нулю).