18c0693f

Дуэли и их семантика


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

Пусть объект выполнил инструкцию:

r (b)

для сепаратного b. После возможного ожидания освобождения b и выполнения сепаратного предусловия объект захватывает b, становясь его текущим владельцем. От имени владельца начинается выполнение r на b, но в некий момент времени, когда действие еще не завершилось, другой сепаратный объект, претендент, выполняет вызов:

s (c)

Пусть сущность c сепаратная и присоединена к тому же объекту, что и b. В обычном случае претендент будет ждать завершения вызова r. Но что случится, если претендент нетерпелив?

С помощью процедур класса CONCURRENCY можно обеспечить необходимую гибкость. Владелец мог уступить, вызвав процедуру yield, означающую: "Я готов отдать свое владение более достойному". Конечно, большинство владельцев не будут столь любезны: если вызов yield явно не выполнен, то владелец будет удерживать то, чем владеет. Сделав уступку, владелец позже может от нее отказаться, вернувшись к установленному по умолчанию поведению, для чего использует вызов процедуры retain.

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

Для возврата к обычному поведению с ожиданием владельца претендент может использовать вызов процедуры wait_turn.

Вызов одной из этих процедур класса CONCURRENCY будет сохранять свое действие до тех пор, пока другая процедура его не отменит.
Отметим, что эти два набора не исключают друг друга. Например, претендент может одновременно использовать insist, требуя специальной обработки, и yield, допуская прерывание своей работы другими. Можно также добавить схему с приоритетами, в которой претенденты ранжированы в соответствии с приоритетами, но здесь мы не будем ее уточнять.

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

Таблица 30.3. Семантика дуэлейВладелецПретендентWait_turndemandinsist
retainПретендент ждетИсключение у претендентаВладелец ждет
yieldПретендент ждетИсключение в программе владельцаИсключение в программе владельца
"Программа владельца", в которой возбуждается исключение в двух нижних правых клетках, - это программа поставщика, исполняемая от лица владельца. При отсутствии retry она будет передавать исключение владельцу, а претендент будет получать объект.

Как вы помните, каждый вид исключений имеет свой код, доступный через класс EXCEPTIONS. Для выделения исключений, вызванных ситуациями из приведенной таблицы, класс предоставляет запрос is_concurrency_interrupt.