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

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

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

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


person Giovanni Funchal    schedule 28.07.2009    source источник
comment
О неблокировке, вероятно, лучше всего думать с точки зрения предотвращения опасностей прогресса (и может даже включать спин-блокировки и внутренние потоки). Каждый вызов функции возвращает своевременный результат или возвращает частичную работу (сопрограмма yield, обещание или обратный вызов по завершении). Блокировка — это стратегия корректности, которая имеет опасности правильности и опасности прогресса, такие как «мертвая-при-удержании-блокировка» и «закон Амдала». Другая неблокирующая стратегия корректности и стратегия прогресса, использующая коммутативные свойства (неблокирующие структуры, неизменяемые), могут быть уместны.   -  person Rob    schedule 13.03.2015


Ответы (5)


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

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

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

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

То, как они реализованы, путем изменения состояний процесса и ожидания возникновения прерывания или события.

person Vivek Sharma    schedule 28.07.2009
comment
Если я понял, то замки блокируют? - person Giovanni Funchal; 28.07.2009
comment
@Helltone - обычно блокировка блокируется только в том случае, если ее уже использует кто-то другой. - person Eric Petroelje; 28.07.2009
comment
Эти комментарии сбивают меня с толку. Итак, вы говорите, что «без блокировки» означает, что завершение других не зависит от вас самих, а «неблокировка» означает, что само завершение не зависит от других. Это то, что вы имеете в виду? - person Giovanni Funchal; 28.07.2009
comment
@Helltone - нет ничего лучше беззамкового. Я еще раз очень четко повторяю: не следуйте английским значениям слов, постарайтесь подумать по-новому. - person Vivek Sharma; 28.07.2009
comment
Более запутанно говорить, что блокировка только блокирует, поскольку вы смешиваете здесь английский язык с терминологией. Блокировка означает, что вы не можете получить доступ к ресурсу, пока ресурс не будет освобожден от блокировки. Если вы человек, который заблокировал ресурс, вы можете его использовать, если вы не тот человек, который заблокировал ресурс, вы не можете его использовать, если только он не будет освобожден вызовом человека/функции, который заблокировал ресурс (CDrom) . Блокировка означает ожидание поступления данных с компакт-диска, если данные не получены, продолжайте ждать, что означает, что если на компакт-диске нет компакт-диска с некоторыми данными, продолжайте искать компакт-диск на компакт-диске. - person Vivek Sharma; 28.07.2009
comment
Блокировка и блокировка - два разных понятия. - person Vivek Sharma; 28.07.2009
comment
@Vivek чем они отличаются? - person Giovanni Funchal; 31.07.2009
comment
Некоторые языки позволяют вам попытаться получить блокировку, но немедленно возвращаются, если вы не можете ее получить, чтобы не блокировать. Если вы можете вызвать функцию, и она гарантированно продолжает выполняться или возвращаться в установленный срок, то она не блокирует. - person Rob; 13.03.2015

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

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

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

Обновить

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

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

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

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

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

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

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

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

  • IO может быть блокирующим/неблокирующим, блокировка может быть блокирующим/неблокирующим.
  • Помимо того, что данные не готовы, запрос ввода-вывода может быть заблокирован, потому что файл заблокирован другим процессом.
person Draemon    schedule 28.07.2009
comment
Блокировка используется не только для доступа к файлам, но хорошо, я понимаю ваш ответ. Я не уверен, что они совершенно разные, возможно, одно подразумевает другое? или в некоторых контекстах они одинаковы, но не в целом. Тогда мой вопрос: какие контексты? - person Giovanni Funchal; 28.07.2009
comment
Конечно, блокировка применима ко всем видам доступа — простой пример — доступ к файлам. Это ортогональные проблемы, и вы можете иметь одно без другого. - person Draemon; 28.07.2009
comment
@Draemon, ты можешь иметь одно без другого. Примеры были бы очень кстати здесь. - person Giovanni Funchal; 28.07.2009
comment
Примеров пока нет, но объяснение - person Draemon; 28.07.2009

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

flock(fh, LOCK_SH | LOCK_NB);

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

person chaos    schedule 28.07.2009

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

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

person Eric Petroelje    schedule 28.07.2009

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

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

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

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

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

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

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

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

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

person Giovanni Funchal    schedule 28.07.2009