Skip to content

Latest commit

 

History

History
204 lines (173 loc) · 15.2 KB

3-actors.md

File metadata and controls

204 lines (173 loc) · 15.2 KB

Блок "Модель акторов, процессы"

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

Стандартная документация

Материалы для изучения

Вопросы

  • В чем преимущество операции spawn_link/1 перед комбинацией spawn/1 + link/1. Приведите пример ситуации, когда последовательность двух операций работает неправильно по сравнению с атомарной операцией spawn_link.
  • Оболочка Erlang (shell) также является процессом. Как просмотреть список всех сообщений, которые попали в почтовый ящик процесса оболочки?
  • За что отвечает ключевое слово after в примитиве приема сообщений?
  • Обмен сообщениями асинхронный. Как сделать синхронный обмен сообщениями? Как добиться взаимоблокировки процессов?

Упражнения

3.1. База данных

За основу возьмите модуль db из предыдущего задания, оформите это в виде процесса. API примерно такой же, с небольшими изменениями:

db:new() => Pid.  %% Возвращает pid созданного процесса.
db:destroy(Db) => ok.

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

db:write(Key, Element, Db) => ok | {error, Reason}. 

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

db:delete(Key, Db) => ok | {error, Reason}.
db:read(Key, Db) => {ok, Element} | {error, instance}.
db:match(Element, Db) => [Keyl, ..., KeyN].

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

proc(State) ->
    NewState = receive
        Msg ->
            %% ...какие то вычисления с термами Msg и State,
            %% возвращающие новое состояние NewState...
    end,
    proc(NewState).

3.2. Parallelisation

-module(pmap).
-compile(export_all).

parallel(Funs) ->
    Self = self(),
    SpawnProc = fun(Func) ->
        spawn(fun() ->
            Result = Func(),
            Self ! {self(), Result}
        end)
    end,
    Pids = [SpawnProc(Fun) || Fun <- Funs],
    get_result(Pids, []).

get_result([], Acc) ->
    lists:reverse(Acc);
get_result([First|Pids], Acc) ->
    receive
        {First, Result} ->
            get_result(Pids, [{First, Result}|Acc])
    end.

На основе вышеприведенного примера реализуйте следующее:

  • параллелизованную версию функции map;
  • параллелизованную версию функции foldl. У такой версии функции будут достаточно весомые орграничения в применении, она уже не будет достаточно универсальной по сравнению с обычной функцией свертки. Что это за ограничения?
  • скомбинируйте решения и реализуйте простой map/reduce.

Этюды

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

Братство Кольца

В Галактике Млечный Путь очень много звездных систем, в которых есть планеты, населенные разумными цивилизациями. Шли сотни и тысячи лет, и постепенно эти цивилизации стали обнаруживать друг друга и налаживать между собой связь. Таким же образом и цивилизация планеты Земля наладила связь с нашими космическими друзьями. Однако межгалактическая связь с должным качеством и надежностью - мероприятие крайне затратное энергетически, и сеансы проводятся раз в сто лет и на проведение одного такого сеанса расходуется энергия всей планеты плюс части Солнечной системы. Со временем организовалось Великое Кольцо - связь между цивилизациями передается по Кольцу, от системы к системе. Такой вариант оказался наиболее выгодным для всех цивилизаций. Есть договоренность, от кого они принимают послание и кому его передают дальше. Если цивилизация решается послать сообщение (весьма немаленькое, ведь за 100 лет накапливается масса сведений!), то она передает его всего лишь одной звездной системе, цивилизация которой передает сообщение дальше. Таким образом, межзвездные знания распространяются по Кольцу. Пример такой схемы передач выглядит следующим образом: Земля -> Вега -> Сириус -> Альтаир -> Земля. Однако, с такой организацией связи есть определенные проблемы. Первая: через сотни лет к нам может вернуться наша же передача многосотлетней давности. Как ее распознать и не передавать дальше? Вторая проблема - цивилизации недолговечны с точки зрения Вселенной и даже высокоразвитые цивилизации могут погибнуть. Как понять, что передача прервалась и надо восстанавливать Кольцо? Проблему облегчает то, что гибель высокоразвитой цивилизации - событие с весьма низкой вероятностью, поэтому обнаружение всего лишь одного пропавшего звена и восстановление цепи передач обеспечит достаточную надежность системы. Также для Межагалктического совета очень важно отслеживать состояние цивилизаций, поэтому было принято решение о том, что цивилизация, инициировавшая передачу, при приеме своей же собственной передачи делает ее повторную трансляцию, добавляя к старым сведениям новые данные, и такой пакет данных гуляет по Кольцу некоторое количество раз. Таким образом, каждая цивилизация может судить по содержимому посланий, что с ее братьями по разуму все хорошо, или же наоборот, все плохо, и надо принимать срочные меры. Совет Звездоплавания организовывает рабочую группу, которая должна предоставить виртуальную модель такой системы, чтобы отработать на ней всевозможные ситуации. Необходимо разработать такую модель.

Sun Post

С приходом эпохи межпланетных перелетов организация под названием "Почта России" существенно расширила поле своей деятельности, и теперь сменила название на "Почта Солнечной системы". C изменением масштабов перевозок меняются и масштабы проблем. Для начала логистам такой организации следует понять, на какие планеты и города на этих населенных пунктах вообще возможна доставка. К примеру, посылку с Марса на Землю можно доставить только через Юпитер (эх...), а вот на Меркурий следуют прямые грузовые рейсы. А есть такие места, до которых нет никаких маршрутов. Как быть? Как обнаруживать такие пункты? И как быстро понять, может ли бабушка, живущая на Венере, отправить своему любимому тринадцатому внуку, живущему на Титане, посылку в виде маленького тортика весом в тонну?

Три закона робототехники*

  • Создайте процесс, имитирующий поведение робота. Робот должен выполнять команду перемещения step, поворота {rotate, Direction}, где Direction принимает два значения: right и left.
  • Запустите несколько роботов и заставьте их перемещаться по некоторому полю. Необходимо обрабатывать ситуации столкновения. Продумайте методы синхронизации процессов.
  • На выполнение каждой команды step робот затрачивает определенное количество энергии. Когда энергии становится ниже определенного порога, робот начинает искать станцию зарядки. На расстоянии одной клетки от станции робот заряжается. Зарядившись, он может дальше предаваться праздному шатанию по полю. Поместите станцию зарядки в какую нибудь клетку виртуального поля. Научите роботов заботиться о своем энергетическом балансе.

Результаты перемещения роботов в виртуальном мире фиксируйте в текстовом файле. Это поможет вам в будущем визуализировать все перемещения роботов по полю.

Мэр планеты Шелезяка

Роботы живут на планете Шелезяка. Но вот проблема: планете нужен мэр. Поскольку все роботы обладают равными умениями (потенциально), то и договориться им непросто. Организуйте между ними выборную гонку, в ходе которой они смогут договориться, кто из них станет мэром.

Раньше роботы поступали так: на Шелезяку временно приглашается робот-судья, который просит всех роботов загадать случайное число, и дальше судья по этим числам определяет, кто становится мером. Если же несколько роботов загадали одно и то же число, оказавшееся максимальным, судья просит проигравших роботов удалиться из зала заседаний и организовывает следующий раунд для оставшихся роботов. Эта процедура повторяется до тех пор, пока не останется один победитель. После чего робот-судья объявляет мэра и улетает.

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

К сожалению, не все вечно, и даже стойкие роботы могут ломаться, в том числе и мэр планеты Шелезяка. Как обнаружить, что мозги мэра заржавели и пора его отправлять на свалку, а после этого выбрать нового мэра?