От переводчиков. Эту коротенькую статью Дейкстры, которой уже 57 лет, Лесли Лампорт назвал «работой, которая начала всю область конкурентных и распределенных алгоритмов». Но на Хабре её до сих пор вроде бы не переводили. Поскольку мы скоро проведём конференцию Hydra, которая посвящена именно этой области, решили восполнить этот пробел. Кстати, как думаете, как лучше переводить на русский слово concurrent? Мы выбрали вариант «конкурентный», но консенсуса тут вроде бы нет.

Эдсгер В. Дейкстра
Технический университет Эйндховена, Нидерланды

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

Введение

В данной работе приводится решение проблемы, вопрос о разрешимости которой, насколько известно автору, остается открытым по крайней мере с 1962 года. Работа состоит из трех частей: проблема, решение и доказательство. Хотя постановка задачи поначалу может показаться несколько академической, автор надеется, что любой, кто знаком с логическими проблемами, возникающими при взаимодействии компьютеров, оценит значимость того факта, что эта проблема в принципе может быть решена. 

Проблема

Для начала рассмотрим N компьютеров, каждый из которых исполняет свой процесс, который для наших целей можно считать циклическим. В каждом из циклов имеется так называемая "критическая секция", притом компьютеры должны быть запрограммированы таким образом, чтобы в любой момент времени только один из этих N циклических процессов находился в своей критической секции. Для того чтобы реализовать это взаимное исключение выполнения критических секций, компьютеры могут общаться друг с другом через хранилище. Запись в это хранилище или неразрушающее считывание из него — это неразделимые операции; то есть, когда два или более компьютера пытаются одновременно взаимодействовать (либо для чтения, либо для записи) с одним и тем же хранилищем, эти операции будут происходить одна за другой, но в неизвестном порядке.

Решение должно удовлетворять следующим требованиям.

(a) Решение должно быть симметричным для N компьютеров; поэтому недопустимо вводить фиксированный приоритет.

(b) Не допускаются никакие предположения об относительных скоростях этих N компьютеров; мы даже не можем предполагать, что их скорости постоянны во времени.

(c) Если любой из компьютеров прекратил работу однозначно за пределами своей критической секции, недопустимо, чтобы это привело к потенциальной блокировке остальных.

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

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

Решение

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

Хранилище содержит:

Boolean array b, c[1:N]; integer k

Целое число k будет удовлетворять 1 ≤ k ≤ N, b[i] и c[i] могут быть изменены только i-тым компьютером; при этом они могут быть прочитаны другими. Предполагается, что все компьютеры начинают свою работу далеко за пределами своих критических секций, при том, что все упомянутые Булевы массивы установлены в значении истина. Начальное значение k не играет роли.

Программа для i-того компьютера (1 ≤ i ≤ N) приведена ниже:

Доказательство

Начнем с того, что решение является безопасным в том смысле, что никакие два компьютера не могут одновременно находиться в своей критической секции. Поскольку единственным способом попасть в критическую секцию является выполнение составного выражения Li4 без возврата к Li1, т.е. обнаружение истинности всех остальных c после того, как собственное c стало ложным.

Вторая часть доказательства должна показать, что никакой бесконечной блокировки типа "После тебя"-"После тебя" произойти не может; а именно, когда ни один из компьютеров не находится в своей критической секции, из зацикленных компьютеров (т.е. прыгающих назад в Li1)  хотя бы один — а значит, ровно один — будет допущен в свою критическую секцию в положенное время.

Если k-й компьютер не входит в число зацикленных, то b[k] будет истинным, а зацикленные компьютеры все будут обнаруживать k ≠ i. В результате один или несколько из них найдут в Li3 Булево b[k]истинным и, следовательно, один или несколько решат присвоить "k := i". После первого присваивания "k := i", b[k] становится ложным и никакие новые компьютеры не могут снова решить присвоить новое значение k. Когда все решенные присваивания k выполнены, k будет указывать на один из зацикленных компьютеров и не будет менять своего значения на время, а именно, пока b[k] не станет истинным, т.е. пока k-й компьютер не завершит свою критическую секцию. Как только значение k больше не будет меняться, k-й компьютер будет ждать (по составному высказыванию Li4), пока все остальные c станут истинными, но эта ситуация обязательно возникнет, если уже не возникла, поскольку все остальные зацикленные компьютеры будут вынуждены установить своё c истинным, так как найдут k ≠ i. И на этом, по мнению автора, доказательство завершается.

Комментарии (8)


  1. victor-homyakov
    20.05.2022 20:59

    Можно было не полениться и вместо картинки дать программу текстом. Заодно и фразы на английском в ней перевести на русский, раз уж в остальном тексте слова "critical section" переведены.


    1. phillennium
      20.05.2022 22:32
      +3

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

      Решил, что раз это часть академической работы, а не код с гитхаба, пусть от греха подальше будет «академической» картинкой, чтобы авторский замысел точно ни в чём не сломался)


  1. gleb_l
    20.05.2022 23:14
    +2

    Хоть код на псевдоязыке (или может, алголе?) выглядит по современным меркам коряво - алгоритм гарантированного получения монопольного доступа к ресурсу без аппаратной поддержки (типа xchg) - такой же красивый и фундаментальный кит computer science, как шифрование без обмена private-ключами. При всем суммарном количестве интеллекта, которое было приложено в золотые времена развития теории и практики аппаратного и программного построения компьютеров, вовлеченным большинством такие вещи воспринимались, как невозможные/невероятные.


  1. funca
    21.05.2022 00:05

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


  1. Sergey_Kovalenko
    21.05.2022 13:23
    +2

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

    Только за одно это побуждение + в карму и к статье.

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

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


    1. funca
      22.05.2022 12:22

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


  1. VT100
    21.05.2022 22:11

    Конкурентный — соревновательный?


    1. funca
      22.05.2022 12:44

      Concurrency в переводе означает одновременность, с латинским корнем - согласие. Основная идея здесь обозначить сам факт одновременного исполнения, которое может приводить к характерным противоречиям.