Что такое спин-блокировка в Linux?

Если UUCP установлен в системе, можно использовать команду cu, например.

 $ cu -l /dev/ttyS0 -s 9600
33
18.12.2017, 02:43
4 ответа

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

Ядро Linux использует спин-блокировки для многих вещей, такой, отправляя данные на конкретное периферийное устройство. Большая часть периферии не разработана для обработки нескольких одновременных обновлений состояния. Если две различных модификации должны произойти, нужно строго следовать за другим, они не могут наложиться. Спин-блокировка обеспечивает необходимую защиту, гарантируя, чтобы модификации произошли по одному.

Спин-блокировки являются проблемой потому что, вращая блоки что ядро процессора потока от выполнения любой другой работы. В то время как ядро Linux действительно предоставляет многозадачные услуги программам пространства пользователя, работающим под ним, который многозадачное средство общего назначения не расширяет до кода ядра.

Эта ситуация изменяется и была для большей части существования Linux. Через Linux 2.0, ядро было почти просто однозадачной программой: каждый раз, когда ЦП выполнял код ядра, только одно ядро процессора использовалось, потому что была единственная спин-блокировка, защищающая все совместно используемые ресурсы, названные Большой блокировкой ядра (BKL). Начинаясь с Linux 2.2, BKL медленно разбивается во многие независимые блокировки, что каждый защищает более сфокусированный класс ресурса. Сегодня, с ядром 2.6, BKL все еще существует, но это только используется действительно старым кодом, который не может быть с готовностью перемещен еще в некоторую детализированную блокировку. Для многоядерного поля теперь довольно возможно иметь каждый ЦП, выполняющий полезный код ядра.

Существует предел утилите разбивания BKL, потому что ядро Linux испытывает недостаток в общей многозадачности. Если ядро процессора получает заблокированное вращение на спин-блокировке ядра, для этого нельзя повторно определить задачу, для движения делают что-то еще, пока блокировка не выпущена. Это просто находится и вращается, пока блокировка не выпущена.

Спин-блокировки могут эффективно оказаться монстром поле с 16 ядрами в одножильное поле, если рабочая нагрузка такова, что каждое ядро всегда ожидает единственной спин-блокировки. Это - основной предел масштабируемости ядра Linux: удвоение ядер процессора от 2 до 4, вероятно, почти удвоит скорость поля Linux, но удвоение его от 16 до 32, вероятно, не будет с большинством рабочих нагрузок.

36
27.01.2020, 19:37
  • 1
    @Warren: Несколько сомнений - я хотел бы знать больше об этой Большой Блокировке Ядра и ее последствиях. Я также вмятина понимает, что последний абзац "удваивающиеся ядра процессора от 2 до 4, вероятно, почти удвоит скорость поля Linux, но удвоение его от 16 до 32, вероятно, не будет" ре –  Sen 22.12.2010, 19:40
  • 2
    : последствия BKL: Я думал, что ясно дал понять выше. Только с одним привязывают ядро, любое время, которое два ядра пытаются сделать, что-то защищенное BKL, одно ядро заблокировано в то время как первые концы с помощью его защищенного ресурса. Чем более мелкомодульный блокировка, тем ниже шанс, что это произойдет, таким образом, большее загрузка процессора. ре –  Warren Young 22.12.2010, 20:01
  • 3
    : удвоение: Я подразумеваю, что существует закон убывающей доходности при добавлении ядер процессора к компьютеру. В то время как количество увеличений ядер, также - шанс, что два или больше из них должны будут получить доступ к ресурсу, защищенному конкретной блокировкой. Увеличение гранулярности блокировки уменьшает возможности таких коллизий, но существуют издержки в добавлении слишком многих, также. Можно легко видеть это в суперкомпьютерах, которые часто имеют тысячи процессоров в эти дни: большинство рабочих нагрузок неэффективно на них, потому что они не могут постараться не бездействовать много процессоров из-за конкуренции совместно используемого ресурса. –  Warren Young 22.12.2010, 20:07
  • 4
    В то время как это - интересное объяснение (+1 для того), я не думаю, что это эффективно при передаче различия между спин-блокировками и другими видами блокировок. –  Gilles 'SO- stop being evil' 22.12.2010, 22:55
  • 5
    Если Вы хотите знать различие между спин-блокировкой и, скажем, семафором, это - другой вопрос. Другой хороший, но тангенциальный вопрос, что является им о дизайне ядра Linux, который делает спин-блокировки хорошим выбором вместо чего-то более общего в коде пространства пользователя, как взаимное исключение. Этот ответ бродит много, как. –  Warren Young 23.12.2010, 03:53

Спин-блокировка - когда процесс постоянно опрашивает относительно блокировки, которая будет удалена. Это считают плохим, потому что процесс использует циклы (обычно) напрасно. Это не является определенным для Linux, но общий шаблон программирования. И в то время как это обычно считают плохой практикой, это - на самом деле, правильное решение; существуют случаи, где стоимость использования планировщика выше (с точки зрения циклов ЦП), чем стоимость нескольких циклов, которые спин-блокировка, как ожидают, продлится.

Пример спин-блокировки:

#!/bin/sh
#wait for some program to clear a lock before doing stuff
while [ -f /var/run/example.lock ]; do
  sleep 1
done
#do stuff

Часто существует способ избежать спин-блокировки. Для этого конкретного примера существует инструмент Linux, названный inotifywait (он обычно не устанавливается по умолчанию). Если бы это было записано в C, то Вы просто использовали бы inotify API, который обеспечивает Linux.

Тот же пример, с помощью inotifywait показывает, как выполнить то же самое без спин-блокировки:

#/bin/sh
inotifywait -e delete_self /var/run/example.lock
#do stuff
11
27.01.2020, 19:37
  • 1
    , Какова роль планировщика там? Или это имеет какую-либо роль? –  Sen 22.12.2010, 16:16
  • 2
    В методе спин-блокировки планировщик возобновляет процесс каждая ~1 секунда, чтобы сделать ее задачу (который является просто проверкой существование файла). В inotifywait примере планировщик только возобновляет процесс, когда дочерний процесс (inotifywait) выходит. Inotifywait также спит; планировщик только возобновляет его, когда inotify случай происходит. А-ч –  Shawn J. Goff 22.12.2010, 16:32
  • 3
    Таким образом, как этот сценарий обрабатывается в системе ядерного процессора? –  Sen 22.12.2010, 19:35
  • 4
    @Sen: Это объяснено скорее хорошо в Драйверах устройств Linux. –  Gilles 'SO- stop being evil' 22.12.2010, 22:57
  • 5
    Тот сценарий удара является плохим примером спин-блокировки. Вы приостанавливаете процесс, заставляющий это засыпать. Спин-блокировка никогда не спит. На одноядерной машине это просто приостанавливает планировщик и продолжает (без активного ожидания) –  Martin 14.12.2017, 04:27

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

Теперь попытка и продолжается, использует намного меньше времени затем попытка и блок. Скажем, в настоящий момент то, что "пытаются продолжиться", возьмет меня, единица времени и "пытается, блок" возьмет сто.

Теперь давайте в настоящий момент предположим, что в среднем поток возьмет 4 единицы времени, содержащие блокировку. Расточительно ожидать 100 единиц. Так вместо этого Вы пишете, что цикл "пытается, продолжается". На дальше пытаются, Вы будете обычно получать блокировку. Это - спин-блокировка. Это называют этим, потому что поток удерживает вращение на месте, пока это не получает блокировку.

Добавленные меры по обеспечению безопасности состоят в том, чтобы ограничить количество раз выполнения цикла. Таким образом в примере Вы делаете для цикла выполненный, например, шесть раз, если он перестал работать затем, Вы "пытаетесь блок".

Если Вы знаете, что поток будет всегда содержать блокировку для, говорят, что 200 единиц, то Вы тратите впустую машинное время для каждого, пытаются продолжиться.

Таким образом в конце, спин-блокировка может быть очень эффективной или расточительной. Это расточительно, когда "типичное" время для содержания блокировки выше затем время, это берет, чтобы "попытаться заблокироваться". Эффективно, когда типичное время для содержания блокировки намного меньше затем время, чтобы 'попытаться заблокироваться".

Ps: книга для чтения на потоках является "Краткой информацией Потока", если можно все еще найти его.

7
27.01.2020, 19:37
  • 1
    удерживает вращение на месте, пока это не получает блокировку. Вы могли сказать мне, что это вращает? Похож на это, это прибывает в wait_queue и помещается в выполнение Планировщиком? Возможно, я пытаюсь войти в низкий уровень, но все еще наклон содержит мое сомнение. –  Sen 23.12.2010, 16:32

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

take the lock
use the resource
release the lock

Взятие блокировки не возможно, если другая задача уже взяла его. (Думайте о блокировке как о физическом маркерном объекте. Или объект находится в секции, или у кого-то есть он в их руке. Только человек, держащий объект, может получить доступ к ресурсу.) Так “берут блокировку”, действительно означает, “ожидают, пока ни у кого больше нет блокировки, затем возьмите ее”.

С высокоуровневой точки зрения существует два главных способа реализовать блокировки: спин-блокировки и условия. Со спин-блокировками, предпринимая меры блокировки, просто “вращающиеся” (т.е. делающие ничто в цикле) ни до кого еще, имеет блокировку. С условиями, если задача пытается взять блокировку, но заблокирована, потому что другая задача содержит ее, вновь прибывший вводит очередь ожидания; операция выпуска предупреждает любую ожидающую задачу, что блокировка теперь доступна.

(Этих объяснений недостаточно, чтобы позволить Вам реализовать блокировку, потому что я ничего не сказал об атомарности. Но атомарность не важна здесь.)

Спин-блокировки очевидно расточительны: ожидающая задача продолжает проверять, взята ли блокировка. Итак, почему и когда это используется? Спин-блокировки являются часто очень дешевыми для получения в случае, где блокировка не сохранена. Это делает это привлекательным, когда шанс для блокировки, которая будет сохранена, является маленьким. Кроме того, спин-блокировки только жизнеспособны, если получение блокировки, как ожидают, не займет много времени. Таким образом, спин-блокировки имеют тенденцию использоваться в ситуациях, где они останутся сохраненными в течение очень короткого времени, так, чтобы большинство попыток, как ожидали, успешно выполнится на первой попытке и тех, которым нужно ожидание, не долго ждут.

Существует хорошее объяснение спин-блокировок и другие механизмы параллелизма ядра Linux в Драйверах устройств Linux, главе 5.

5
27.01.2020, 19:37

Теги

Похожие вопросы