В чем разница между безблокирующим и неблокирующим?

StackOverflow https://stackoverflow.com/questions/1193842

Вопрос

В контексте синхронизации структур данных может ли кто-нибудь прояснить разницу между «безблокировкой» и «неблокировкой»?Кажется, что многие люди используют эти термины как взаимозаменяемые, но я еще не уверен, нет ли где-то скрытой какой-то тонкой разницы.

Я имею в виду, что lockless — это «без блокировок», а неблокировка больше похожа на гарантию прогресса.Я подозреваю, что одно подразумевает другое, но не наоборот, я не уверен.

Ссылки приветствуются.

Это было полезно?

Решение

Блокировка – это механизм контроля доступа.Я имею в виду, что вы блокируете ресурс, когда хотите получить к нему эксклюзивный доступ.Заприте дверь, используйте комнату/делайте все, что пожелаете, а теперь откройте комнату для других, чтобы они могли ею воспользоваться.Пока комната заперта, никто другой не мог войти в комнату и, следовательно, не мог ничего сделать.

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

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

Таким образом, БЛОКИРОВКА просто означает, что вы захватываете ресурс на определенное время (если вы его не разблокируете).И БЛОКИРОВКА — это то, что вы заблокированы, а это значит, что вы не можете продолжить, поскольку у вас нет данных, чтобы продолжить или идти вперед.

Способ их реализации: изменение состояний процесса и ожидание возникновения прерывания или события.

Другие советы

Они совершенно разные.

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

Блокировка означает, что метод будет ждать завершения операции перед возвратом.

Обновлять

В ответ на запрос примеров...Я постараюсь добавить примеры, если у меня будет время, а пока вот объяснение возможностей.

У нас есть 3 способа выполнить блокировку:

  • Никто
  • Блокировка.Если замок недоступен, подождите его.
  • Неблокирующий.Если блокировка недоступна, произойдет сбой.

И 2 способа выполнения ввода-вывода:

  • Блокировка.Подождите, пока буферы будут готовы.
  • Неблокирующий.Ошибка, если мы не можем сразу читать/писать

Если мы используем open() и read() как обычно, мы получаем блокировку ввода-вывода.Если нам нужен неблокирующий ввод-вывод, нам нужно передать O_NONBLOCK пометить open(), и read() потом вернется E_AGAINвместо блокировки.

По умолчанию блокировки нет.Мы можем позвонить fcntl() с F_SETLK или F_SETLKW чтобы получить замок.Первый блокируется, если блокировка недоступна, второй терпит неудачу с EACCES или EAGAIN.

Я думаю, что есть два возможных момента путаницы:

  • IO может быть блокирующим/неблокирующим, блокировка может быть блокирующим/неблокирующим.
  • Помимо того, что данные не готовы, запрос ввода-вывода может блокироваться, поскольку файл заблокирован другим процессом.

Да, без замка означает отсутствие запирающего механизма.Неблокирование означает, что вызов будет возвращаться немедленно, а не ждать какого-либо внешнего события (например, снятия блокировки или поступления данных в буфер).Можно иметь блокировки и использовать неблокирующие вызовы, как, например, в вызове

flock(fh, LOCK_SH | LOCK_NB);

что означает «попытайтесь получить блокировку чтения, но если вы не можете, не ждите ее, немедленно вернитесь и скажите мне, что вы не можете».Поведение по умолчанию LOCK_SH («общий замок») без LOCK_NB («неблокирующий») означало бы ожидание доступности блокировки.

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

Кроме того, неблокировка может не означать, что что-то не имеет блокировки.Например, структура данных может использовать блокировки, но иметь некоторые неблокирующие операции, которые не требуют блокировки, и другие блокирующие операции, которые требуют ее.

Предварительный ответ на примере:

Рассмотрим объект (называемый «событием») с двумя методами: wait() и notify().

  • Реализация 1:

    notify() атомарно устанавливает логическое значение. wait() циклы до тех пор, пока логическое значение не станет истинным.Оба без замка, но wait() является блокировка.

  • Реализация 2:

    notify() получает блокировку, устанавливает логическое значение, а затем снимает блокировку. wait() получает блокировку, читает логическое значение, снимает блокировку, и все это в цикле, пока логическое значение не станет истинным.Оба, таким образом, на основе блокировки, блокировка.

  • Реализация 3:

    Первоначально замок используется. notify() проверяет логическое значение и снимает блокировку, если оно истинно. wait() получает блокировку и устанавливает для логического значения значение true. notify() является неблокирующий (спорно, так ли это без замка или нет). wait() является на основе блокировки, блокировка.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top