OberonCore
https://forum.oberoncore.ru/

EXCLUSIVE и AWAIT
https://forum.oberoncore.ru/viewtopic.php?f=31&t=365
Страница 1 из 1

Автор:  Vlad [ Пятница, 12 Январь, 2007 12:09 ]
Заголовок сообщения:  EXCLUSIVE и AWAIT

Почитал доку к ActiveBB. Возник такой вопрос: почему AWAIT не является составной частью EXCLUSIVE? Т.е., чем оправдана логика, когда внутри блока EXCLUSIVE поток останавливается на AWAIT и другие потоки могут входить в другие блоки EXCLUSIVE (и, как я понимаю, в этот же самый блок EXCLUSIVE тоже). По-моему было бы логичней, если бы весь блок EXCLUSIVE выполнялся атомарно, а условие стояло только на входе в такой блок. Буду благодарен за разъяснения и за ссылки.

Автор:  Илья Ермаков [ Пятница, 12 Январь, 2007 12:46 ]
Заголовок сообщения: 

Хороший вопрос, я, честно говоря, призадумался. Такая модель является классической, она пришла еще из концепции монитора, в 70-х годах, а Active Oberon просто видоизменил ее.

Вообще говоря, семантика EXLUSIVE и AWAIT несколько различная - взаимное исклюение и синхронизация - видимо, оправдано было их разделить. В языках с мониторами любая процедура объекта-монитора по определению эксклюзивна, ее даже помечать не надо. А синхронизация может выполняться несколько раз сряду в одной процедуре. Если бы вместо EXCLUSIVE был только AWAIT, то несколько идущих подряд AWAIT вызывали бы рекурсивную блокировку, а в какой момент освобождать каждый ее уровень? А если "встык", то вся процедура станет не атомарной, а кусочно-эксклюзивной. Таки лучше "без фантазий", видимо.

Автор:  Сергей Губанов [ Пятница, 12 Январь, 2007 14:19 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
почему AWAIT не является составной частью EXCLUSIVE?


Потому что EXCLUSIVE нужен сам по себе без относительно того существует ли AWAIT или его нет в природе вовсе.

Vlad писал(а):
По-моему было бы логичней, если бы весь блок EXCLUSIVE выполнялся атомарно, а условие стояло только на входе в такой блок.


Первое что приходит на ум это то что мы можем не захотеть ждать:
Код:
PROCEDURE f;
BEGIN
  ...
  BEGIN{EXCLUSIVE}
    IF ~condition THEN
      IF не-хотим-ждать THEN
        RETURN
      ELSE
        AWAIT(condition)
      END
    END;
    ...
  END;
  ...
END f;

Автор:  Сергей Губанов [ Пятница, 12 Январь, 2007 14:32 ]
Заголовок сообщения: 

В Эйфеле EXCLUSIVE и AWAIT совмещены в одну фичу - так там процедуры называются. Когда фичу вызывают, она пытается залочить все свои аргументы и ожидает выполнения всех предусловий, после чего выполняется атомарно. А для предотвращения взаимоблокировок там введён механизм "борьбы" - это когда потоки начинают внутрь друг друга исключениями бросаться, чтобы тот поток который залочил объект нужный другому разлочил его, а залочивший имеет право отказать в разлочке обработав полученное исключение и т.д.

Автор:  Vlad [ Пятница, 12 Январь, 2007 14:32 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
Вообще говоря, семантика EXLUSIVE и AWAIT несколько различная - взаимное исклюение и синхронизация - видимо, оправдано было их разделить.


Семантика разная. Просто применение AWAIT внутри EXCLUSIVE у меня создает ощущения ломания структуры потока выполнения программы. Что-то типа вложенного в сишный switch условного оператора if, который может в себя включать отдельные case.

Илья Ермаков писал(а):
В языках с мониторами любая процедура объекта-монитора по определению эксклюзивна, ее даже помечать не надо. А синхронизация может выполняться несколько раз сряду в одной процедуре.


Если все процедуры эксклюзивны, то не ведет ли это к потере производительности из-за того, что часть кода, которая не модифицирует состояние никогда не будет выполняться параллельно?

Илья Ермаков писал(а):
Если бы вместо EXCLUSIVE был только AWAIT, то несколько идущих подряд AWAIT вызывали бы рекурсивную блокировку, а в какой момент освобождать каждый ее уровень?


Не понял. Откуда возникнет блокировка?

Автор:  Vlad [ Пятница, 12 Январь, 2007 14:45 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Сергей Губанов писал(а):
Vlad писал(а):
По-моему было бы логичней, если бы весь блок EXCLUSIVE выполнялся атомарно, а условие стояло только на входе в такой блок.


Первое что приходит на ум это то что мы можем не захотеть ждать:


Этот пример вырождается в:

Код:
 
AWAIT(не-хотим-ждать OR condition);
IF не-хотим-ждать THEN
    RETURN


Может есть другие примеры?

Автор:  Vlad [ Пятница, 12 Январь, 2007 14:47 ]
Заголовок сообщения: 

Сергей Губанов писал(а):
В Эйфеле EXCLUSIVE и AWAIT совмещены в одну фичу - так там процедуры называются. Когда фичу вызывают, она пытается залочить все свои аргументы и ожидает выполнения всех предусловий, после чего выполняется атомарно.


Вот такой подход у меня не вызывает никаких противоречивых чувств. Может где-то есть сравнение таких различных подходов с описанием неочевидных достоинств/недостатков?

Автор:  Сергей Губанов [ Пятница, 12 Январь, 2007 17:37 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
Код:
 
AWAIT(не-хотим-ждать OR condition);
IF не-хотим-ждать THEN
    RETURN

Не совсем понятно что здесь написано. Если я правильно это понял, то лучше бы записать это как-то так:
Код:
IFEXWAIT не_хотим_ждать OR condition THEN
   IF не_хотим_ждать THEN RETURN END;
   ASSERT(condition);
   ...
END

Здесь я использовал выдуманный синтаксический блок
IFEXWAIT ... THEN ... END
объединяющий в себе обычные EXCLUSIVE и AWAIT.
Так вот, этот код, хоть и имеет свой смысл, но он не эквивалентен исходному коду:
Код:
BEGIN{EXCLUSIVE}
  IF ~condition THEN
    IF не_хотим_ждать THEN
      RETURN
    ELSE
      AWAIT(condition)
    END
  END;
  ASSERT(condition);
  ...
END

а эквивалентен такому коду:
Код:
BEGIN{EXCLUSIVE}
  AWAIT(не_хотим_ждать OR condition);
  IF не_хотим_ждать THEN RETURN END;
  ASSERT(condition);
  ...
END

логика работы у них разная: первый всё таки дожидается наступления события condition = TRUE, а второй прерывает ожидание когда кто-то изменит переменную не_хотим_ждать на TRUE.

Допустим у нас есть две переменные: "не_хотим_ждать" и "надоело_ждать", тогда возможен код:
Код:
BEGIN{EXCLUSIVE}
  IF ~condition THEN
    IF не_хотим_ждать THEN
      RETURN
    ELSE
      AWAIT(надоело_ждать OR condition);
      IF надоело_ждать THEN RETURN END
    END
  END;
  ASSERT(condition);
  ...
END

реализовать его с помощью блока IFEXWAIT ... THEN ... END, кажется невозможно.

Кстати, EXCLUSIVE - блоки в Active Oberon не могут быть вложенными (используется быстрое, но нереентерабельное залочивание объекта this).

Автор:  Сергей Губанов [ Пятница, 12 Январь, 2007 17:55 ]
Заголовок сообщения: 

Vlad писал(а):
Может где-то есть сравнение таких различных подходов с описанием неочевидных достоинств/недостатков?


Когда прошлым летом Бертнанд Мейер приезжал с лекцией в Нижегородский университет, я у него спросил после лекции, что он думает по поводу механизма EXCLUSIVE-AWAIT реализованном в Active Oberon. Он ответил, что, мол, такой подход есть, но он не берётся судить что лучше, время покажет.

Автор:  Vlad [ Пятница, 12 Январь, 2007 18:09 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Сергей Губанов писал(а):
Vlad писал(а):
Код:
 
AWAIT(не-хотим-ждать OR condition);
IF не-хотим-ждать THEN
    RETURN

Не совсем понятно что здесь написано. Если я правильно это понял, то лучше бы записать это как-то так:


Ты правильно понял, AWAIT здесь подразумеват одновременный EXCLUSIVE.

Сергей Губанов писал(а):
Здесь я использовал выдуманный синтаксический блок
IFEXWAIT ... THEN ... END
объединяющий в себе обычные EXCLUSIVE и AWAIT.


Только зачем THEN я не понял.

Сергей Губанов писал(а):
логика работы у них разная: первый всё таки дожидается наступления события condition = TRUE, а второй прерывает ожидание когда кто-то изменит переменную не_хотим_ждать на TRUE.


Ну и что, в обоих случаях получаем нужный результат.

Сергей Губанов писал(а):
Допустим у нас есть две переменные: "не_хотим_ждать" и "надоело_ждать", тогда возможен код:
Код:
BEGIN{EXCLUSIVE}
  IF ~condition THEN
    IF не_хотим_ждать THEN
      RETURN
    ELSE
      AWAIT(надоело_ждать OR condition);
      IF надоело_ждать THEN RETURN END
    END
  END;
  ASSERT(condition);
  ...
END

реализовать его с помощью блока IFEXWAIT ... THEN ... END, кажется невозможно.


Почему невозможно? Вот:

Код:
EXCWAIT(condition OR надоело_ждать OR не_хотим_ждать);
IF condition THEN
END


Сергей Губанов писал(а):
Кстати, EXCLUSIVE - блоки в Active Oberon не могут быть вложенными (используется быстрое, но нереентерабельное залочивание объекта this).


Ну это уже не так принципиально. Хотя мне кажется, что реентерабельное залочивание стоит копейки.

Автор:  Wlad [ Пятница, 12 Январь, 2007 22:00 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
Хотя мне кажется, что реентерабельное залочивание стоит копейки.

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

Автор:  Wlad [ Пятница, 12 Январь, 2007 22:01 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

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

Общиая направленность ваших рассуждений ближе к реализации многозадачности и синхронизации в Аде. Там Хоаровские мониторы выражены "более прямолинейно".

Автор:  Сергей Губанов [ Вторник, 16 Январь, 2007 09:45 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
Почему невозможно? Вот:
Код:
EXCWAIT(condition OR надоело_ждать OR не_хотим_ждать);
IF condition THEN
END


Это совсем не то. Здесь выход из ожидания произойдёт тогда когда кто-то установит переменную не_хотим_ждать в TRUE, а предложенный мной код подразумевает, что мы должны ждать только (надоело_ждать OR condition), в то время как переменная не_хотим_ждать после начала ожидания нас больше не интересует. Она нужна только для входа в ожидание, но не для выхода из него.

Более того, этот код содержит ошибку: значение переменной condition внутри EXCWAIT может быть не равно её же значению в следующей после неё инструкции IF condition THEN, поскольку между выполнениями этих двух инструкций значение переменной condition могло быть изменено другим потоком. Для того чтобы значение переменной condition не изменялось между этими инструкциями нужно чтобы они обе выполнялись внутри одного и того же эксклюзивного блока, т.е. атомарно.

Вот ещё простой пример, который нельзя переписать с помощью EXCWAIT:
Код:
BEGIN{EXCLUSIVE}
  ...
  AWAIT(enter);
  ...
  AWAIT(exit);
  ...
END;

Автор:  Vlad [ Вторник, 16 Январь, 2007 12:58 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Сергей Губанов писал(а):
Vlad писал(а):
Почему невозможно? Вот:
Код:
EXCWAIT(condition OR надоело_ждать OR не_хотим_ждать);
IF condition THEN
END


Это совсем не то. Здесь выход из ожидания произойдёт тогда когда кто-то установит переменную не_хотим_ждать в TRUE, а предложенный мной код подразумевает, что мы должны ждать только (надоело_ждать OR condition), в то время как переменная не_хотим_ждать после начала ожидания нас больше не интересует. Она нужна только для входа в ожидание, но не для выхода из него.


Все равно не понял. Нужное условие проверяется еще раз сразу после EXCWAIT.

Сергей Губанов писал(а):
Более того, этот код содержит ошибку: значение переменной condition внутри EXCWAIT может быть не равно её же значению в следующей после неё инструкции IF condition THEN, поскольку между выполнениями этих двух инструкций значение переменной condition могло быть изменено другим потоком.


Не могло оно быть изменено другим потоком, потому как проверка условия осуществляется с блокировкой доступа для других потоков и если проверка прошла, то блокировка не снимается до конца выполнения функции (или до конца действия блока EXCWAIT).

Сергей Губанов писал(а):
Вот ещё простой пример, который нельзя переписать с помощью EXCWAIT:
Код:
BEGIN{EXCLUSIVE}
  ...
  AWAIT(enter);
  ...
  AWAIT(exit);
  ...
END;


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

Автор:  Сергей Губанов [ Вторник, 16 Январь, 2007 15:39 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
Все равно не понял. Нужное условие проверяется еще раз сразу после EXCWAIT.


Ваше ожидание завершается так сказать "по трём причинам": condition OR надоело_ждать OR не_хотим_ждать, а моё "по двум": надоело_ждать OR condition. Моей ждущей программе, после того как она уже начала ждать, значение переменной не_хотим_ждать уже безразлично.

Vlad писал(а):
блокировка не снимается до конца выполнения функции (или до конца действия блока EXCWAIT).


Вообще-то, в приведённой Вами записи EXCWAIT выглядела как процедура.

Vlad писал(а):
Сергей Губанов писал(а):
Вот ещё простой пример, который нельзя переписать с помощью EXCWAIT:
Код:
BEGIN{EXCLUSIVE}
  ...
  AWAIT(enter);
  ...
  AWAIT(exit);
  ...
END;

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


Наверное не на 2, а на 3.
Код:
BEGIN{EXCLUSIVE}
  f1;
  AWAIT(enter);
  f2;
  AWAIT(exit);
  f3
END;


Мне приходит в голову что-то навроде следующего:
Код:
feature H1 (args...);
begin
  f1(args...);
  H2(args...)
end;

feature H2 (args...); precondition enter;
begin
  f2(args...);
  H3(args...)
end;

feature H3 (args...); precondition exit;
begin
  f3(args...)
end;

Так хотите?

Автор:  Vlad [ Вторник, 30 Январь, 2007 08:59 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Сергей Губанов писал(а):
Вообще-то, в приведённой Вами записи EXCWAIT выглядела как процедура.


Под EXCWAIT я понимаю комбинацию EXCLUSIVE и AWAIT. Этой комбинации соответствует определенная область действия.

Vlad писал(а):
Я бы хотел в данном случае видеть декомпозицию на две отдельных функции, которые совершают законченные действия с объектом.


Я тут еще подумал... В идеале вообще хотелось бы инкапсулировать логику блокировок и эксклюзивного выполнения от всего остального. Т.е., вот этот пример:

Код:
BEGIN{EXCLUSIVE}
  f1;
  AWAIT(enter);
  f2;
  AWAIT(exit);
  f3;
END;


Я бы хотел видеть так:

Код:
BEGIN
  f1;
  o.Enter();
  f2;
  o.Exit();
  f3;
END;


Где Enter/Exit - эксклюзивно-условные методы объекта o. Все остальные методы, не помеченные как эксклюзивно-условные, подразумевают возможность параллельного выполнения.

Автор:  Илья Ермаков [ Вторник, 30 Январь, 2007 11:56 ]
Заголовок сообщения: 

А объект O - это как бы совокупность условий, которых можем ожидать?

Автор:  Vlad [ Вторник, 30 Январь, 2007 12:42 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
А объект O - это как бы совокупность условий, которых можем ожидать?


Совокупность условий + состояние, изменяемое атомарно.

Автор:  Сергей Губанов [ Вторник, 30 Январь, 2007 12:43 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Vlad писал(а):
Т.е., вот этот пример:
Код:
BEGIN{EXCLUSIVE}
  f1;
  AWAIT(enter);
  f2;
  AWAIT(exit);
  f3;
END;

Я бы хотел видеть так:
Код:
BEGIN
  f1;
  o.Enter();
  f2;
  o.Exit();
  f3;
END;



Я Вас не совсем понял. Первый блок кода, будучи записанным без ActiveOberon-истого синтаксического сахара есть вот что:
Код:
...
try
{
  System.Threading.Monitor.Enter(this);
  this.f1();
  while (!this.enter) System.Threading.Monitor.Wait(this);
  this.f2();
  while (!this.exit) System.Threading.Monitor.Wait(this);
  this.f3();
}
finally
{
  System.Threading.Monitor.Exit(this);
}
...

А Ваш код что?

Автор:  Vlad [ Вторник, 30 Январь, 2007 13:05 ]
Заголовок сообщения:  Re: EXCLUSIVE и AWAIT

Сергей Губанов писал(а):
Т.е., вот этот пример:
Код:
BEGIN{EXCLUSIVE}
  f1;
  AWAIT(enter);
  f2;
  AWAIT(exit);
  f3;
END;

А Ваш код что?


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

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/