Якщо я використовую блокування, чи може мій алгоритм все-таки бути без блокування?


10

Поширене визначення безблокового замовлення - це те, що принаймні один процес робить прогрес. 1

Якщо у мене є проста структура даних, така як черга, захищена блокуванням, то один процес завжди може досягти прогресу, оскільки один процес може придбати замок, зробити все, що хоче, і звільнити його.

То чи відповідає воно визначенню без замка?


1 Див., Наприклад, М. Герліхій, В. Лучанко та М. Муар. Синхронізація без перешкод: двосторонні черги як приклад. У розділі «Розподілені обчислення», 2003 р. «Це блокування, якщо воно забезпечує лише те, що якийсь потік завжди прогресує».


3
Я завжди розумів "замок безкоштовно", щоб описати структуру даних та набір алгоритмів, які не використовують блокування, лише невеликий визначений набір операцій з атомною пам'яттю. Наприклад, drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/…
Пол Джонсон

Відповіді:


16

Це не визначення для блокування.

Якщо ви можете гарантувати прогрес, то у вас без тупика , і якщо у вас є можливе завершення кожного запиту, то у вас є голодування , але не блокування.

Я сумніваюся, чи справді ваш простий приклад це дає. Вам потрібні ієрархії блокування та інше, щоб фактично зробити гарантії прогресу, коли задіяно кілька блокувань.


1
Я використовую визначення від М. Герліхія. Методика реалізації об'єднаних даних з високою сумісністю. Операції з мов та систем програмування, 1993 р. "Умова без блокування гарантує, що якийсь процес завжди буде прогресувати, незважаючи на довільну зупинку відмов чи затримки іншими процесами"
Джо Пенсія,

12
@Joe: Це не визначення, воно описує значення. Остерігайтеся помилок зворотного.
Бен Войгт

2
Можна також процитувати М. Герліхі, В. Лучанко та М. Муара. Синхронізація без перешкод: двосторонні черги як приклад. У розділі «Розподілені обчислення», 2003 р. «Це блокування, якщо воно забезпечує лише те, що якийсь потік завжди прогресує».
Джо Пансіонат

1
є також без голоду, який є більш специфічним, ніж без тупикових ситуацій (кожен процес може йти незалежно від того, що роблять інші процеси) зауважте, що петлі CaS (засновані на атомних примітивах) не є
храповиком виродком

5
@Joe: Якщо інший світ називає цю власність тупиковою , я буду використовувати цей термін. Ні, ваш простий приклад не без тупика. Для того, щоб гарантувати, що щось без тупика, вам потрібна не тільки синхронізація, але й гарантія того, що жодна нитка не виконує жодної операції блокування, утримуючи замок. "робити те, що хоче" є надзвичайно розпливчастим і, здається, не дає такої гарантії.
Бен Войгт

11

Я вивчав «Мистецтво багатопроцесорного програмування» 1, і їх текст не вистачає ясності, як і книга, про яку ви посилаєтесь. Ось кілька цитат з TAMPP:

Цитата 1 (Визначення безблокового)

Метод не заблокований, якщо він гарантує, що нескінченно часто якийсь виклик методу закінчується в кінцевій кількості кроків.

Цитата 2 (Визначення розблокування)

очікуване виклик загального методу ніколи не потрібно чекати завершення чергового виклику в очікуванні.

Цитата 3 (заявіть, що без блокування блокується)

Умови прогресу безблокування, що чекає, і без блокування гарантують, що обчислення в цілому досягає прогресу, незалежно від того, як система планує потоки.

Проблема полягає в тому, що претензія в Цитаті 3 очевидно не випливає з визначення в Цитаті 1. Як уже згадувалося, синхронізована черга, здається, задовольняє Цитата 1: нескінченно часто якийсь метод успішно придбає замок і завершиться.

Зазначимо конкретно досить невиразну фразу в цитаті 3: "незалежно від того, як система планує потоки". Цьому не передує формальний опис "системи планування потоків", тому нам залишається реконструювати її властивості, виходячи з наших попередніх уявлень про те, що повинні означати визначення :

  1. система завжди виконує вказівки якогось потоку;
  2. він ніколи не може виконувати вказівки будь- якого потоку;
  3. всі потоки викликають розглянутий метод.

У такій системі спосіб блокування не може бути заблокованим: якщо потік, що тримає замок, більше ніколи не буде запланований до виконання, не буде іншого потоку, який може завершити виклик методу в кінцевій кількості кроків, але все ж буде деякі потоки, які виконують етапи методу. Для більш реалістичної системи, яка гарантує дати час процесора кожному потоку в кінцевому підсумку, визначення повинно явно містити властивість, що не блокує:

Виправлене визначення без замка

Метод є безблоковим, якщо він не блокує, і, крім того, гарантує, що нескінченно часто якийсь виклик методу закінчується в кінцевій кількості кроків.

1 Моріс Херліхі, Нір Шавіт, Мистецтво багатопроцесорного програмування, Elsevier 2008, с. 58-60


1
Формулювання цитати 1 дійсно дивне. Що вони означають під "нескінченно часто"? Очевидно щось інше, ніж "завжди", тож нормально, що метод ніколи не повертається в "деяких" випадках?
Халк

Так, неточна мова рясна. Що все-таки "часто"? Я думаю, що вони означають "в історії нескінченних страт, ця конкретна подія відбувається нескінченно багато разів".
Марко Топольник

5

Термінологія не завжди відповідає, але я думаю, що важливо задати наступні питання щодо запропонованого алгоритму чи системи:

  1. Чи є якась послідовність подій, коли потоки можуть застрягти, чекаючи один одного, навіть якщо всім потокам було дозволено весь час процесора, який вони могли використовувати [якщо так, то це не тупик безкоштовно]
  2. Якщо один потік був заблокований довільно тривалий час, чи може це затримати інші потоки або погіршити роботу системи довільно довгий час [якщо так, то це не блокує].
  3. Чи існує якась хоча б теоретично можлива комбінація планування потоків, яка могла б змусити всі потоки повторно повторювати одні й ті ж операції, при цьому виключаючи роботу один одного, без того, щоб хтось робив прогрес [якщо так, то це не блокування]
  4. Якщо деяким потокам приділяється достатньо часу процесора відносно іншого, вони можуть змусити останній потік продовжувати повторну операцію нескінченно [якщо так, то це не чекає].

Значна частина алгоритмів без блокування полягає не в тому, що вони швидші, ніж алгоритми без блокування, а в тому, що вони не схильні до вмирання, якщо нитка отримує прокладений [зауважте, що така гарантія просто вимагає що алгоритми не блокують, але всі алгоритми без блокування є]. Можна використовувати алгоритм без блокування, але лише якщо спроби отримання блокування включають тайм-аути разом з алгоритмами, щоб гарантувати, що хтось завжди зможе досягти прогресу (наприклад, алгоритм може використовувати CompareExchangeцикл як основний метод арбітражу, але використовувати шлюзи для арбітражу доступу, коли суперечка здається високою; якщо блокування здається, що він тримається надто довго, інші потоки можуть вирішити відмовитися від використання цього блокування та замість цього створити новий.CompareExchange, якщо клієнти відмовляться від блокування, це не ставить під загрозу послідовність системи, хоча це може означати, що код, який тримав старий замок, не виконає жодної роботи, поки він занадто не відмовиться від старого блокування і не стане в порядку нового.


Це відрізняється від стандартної термінології: ваш 2. посилається на стандартне значення неблокування, тоді як 3. посилається на свободу блокування.
Марко Топольник

Я бачив невідповідні терміни використання, і не знаю "офіційного" стандарту. Найголовніше - це те, що існують різні гарантії, які може запропонувати алгоритм, і важливо використовувати алгоритм, який пропонує гарантії, достатні для задоволення вимог програми. Багато паперів охоплюють лише деякі вищезазначені гарантії, але є випадки, коли кожен може мати можливість задовольнити вимоги заявки легше, ніж будь-які інші гарантії, які б відповідали вимогам.
supercat

Я думаю, що існує консенсус, що термінологія, представлена ​​в "Мистецтві багатопроцесорного програмування", є "стандартною".
Марко Тополник

@MarkoTopolnik: Я відредагую публікацію, щоб відповідати тому. Чи подобається вам нова версія ?.
supercat

Класно, дуже приємно.
Марко Топольник

4

Ви повинні подивитися на "визначення", яке ви цитуєте в контексті :

Традиційний спосіб реалізації спільних структур даних - це використання взаємного виключення (блокування) для того, щоб паралельні операції не заважали одна одній. Блокування має ряд недоліків щодо інженерії програмного забезпечення, відмовостійкості та масштабованості (див. [8]). У відповідь дослідники досліджували різні альтернативні методи синхронізації, які не використовують взаємне виключення . Техніка синхронізації не вимагає очікування, якщо вона гарантує, що кожен потік буде продовжувати прогресувати в умовах довільної затримки (або навіть відмови) інших потоків. Він заблокований, якщо забезпечує лише те, що якась нитка завжди досягає прогресу.

Ви використовуєте замки для взаємного виключення, тому це не техніка без блокування, про яку вони говорять.


2

Якщо я використовую блокування, чи може мій алгоритм все-таки бути без блокування?

Це могло бути, але це залежить від алгоритму.

Якщо у мене є проста структура даних, така як черга, захищена блокуванням, то один процес завжди може досягти прогресу, оскільки один процес може придбати замок, зробити все, що хоче, і звільнити його.

То чи відповідає воно визначенню без замка?

Примітка сама по собі .

Якщо крок "робити те, що хоче" не передбачає придбання будь-яких інших блокувань, і це гарантовано завершиться протягом обмеженого часу, то ця конкретна частина вашого алгоритму буде безвідома.

Однак, якщо ці передумови не виконуються, існує хоча б потенціал для тупиків ...


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

1

Приклад, який ви наводите, не є блокувальним з наступної причини.

Підтримка одного потоку набуває замок, і планувальник ОС призупинив потік на нескінченний період часу, тоді весь потік не може досягти прогресу, оскільки жоден не може придбати замок, придбаний підвішеною ниткою.

Взагалі кажучи, алгоритми, які використовують блокування, не є блокувальними.

Зауважте, що без тупиків та без замків - це дві різні концепції. без тупика означає, що немає можливості для глухого кута, але може існувати неполадка, яка може перешкодити всій системі прогресувати. Свобода блокування сильніша за це, оскільки це означає, що деякі потоки в системі завжди досягають прогресу з обмеженою кількістю кроків.


Подивіться на більш ретельне визначення у Вікіпедії: "Алгоритм заблокований, якщо він задовольняє, що коли нитки програми виконуються достатньо довго, принаймні одна з ниток робить прогрес." Це виключає випадок зупинки ниток. Також прогрес в умовах зупинки охоплюється свободою перешкод , а не замкненою свободою .
Марко Топольник

@MarkoTopolnik Ваш коментар зовсім не має сенсу. Свобода замка охоплює обструкцію-свободу. Все, що не є замком, повинно бути без перешкод. І дане вами визначення не виключає припинення потоків.
Чаоран

Будь ласка, подбайте про те, щоб відрізнити "сенс" від "правильний". Мій коментар невірний, що видно з моєї подальшої відповіді. Але визначення Вікіпедії також неправильне або принаймні неоднозначне.
Марко Топольник

@MarkoTopolnik Оскільки ви визнаєте, що ваш коментар невірний, слід видалити його, щоб не плутати інших читачів. Вікіпедія часто неправильна або неоднозначна. Ви можете знайти тонкі визначення на зразок "замок-свобода" в наукових роботах, таких як cs.rochester.edu/~scott/papers/2006_PPoPP_synch_queues.pdf (визначення без замкнення знаходиться в розділі 2.1)
Чаоран

Так, включення властивості, що блокує, як частина визначення свободи блокування - це один із способів зробити це. Про це було сказано в попередній редакції моєї відповіді.
Марко Топольник
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.