[elixir/ru] Concurrency

This commit is contained in:
Ev Bogdanov 2017-08-19 21:55:53 +03:00
parent b4d50ee299
commit 13a89c7fd0

View File

@ -383,4 +383,60 @@ rescue
end
#=> "какая-то ошибка"
## ---------------------------
## -- Параллелизм
## ---------------------------
# Параллелизм в Elixir построен на модели акторов. Для написания
# параллельной программы нам понадобятся три вещи:
# 1. Создание процессов
# 2. Отправка сообщений
# 3. Приём сообщений
# Новый процесс создаётся функцией `spawn`, которая принимает функцию
# в качестве аргумента.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0>
# `spawn` возвращает идентификатор процесса (англ. process identifier, PID).
# Вы можете использовать PID для отправки сообщений этому процессу. Сообщения
# отправляются через оператор `send`. А для приёма сообщений используется
# механизм `receive`:
# Блок `receive do` ждёт сообщений и обработает их, как только получит. Блок
# `receive do` обработает лишь одно полученное сообщение. Чтобы обработать
# несколько сообщений, функция, содержащая блок `receive do`, должна рекурсивно
# вызывать себя.
defmodule Geometry do
def area_loop do
receive do
{:rectangle, w, h} ->
IO.puts("Площадь = #{w * h}")
area_loop()
{:circle, r} ->
IO.puts("Площадь = #{3.14 * r * r}")
area_loop()
end
end
end
# Скомпилируйте модуль и создайте процесс
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Альтернативно
pid = spawn(Geometry, :area_loop, [])
# Отправьте сообщение процессу
send pid, {:rectangle, 2, 3}
#=> Площадь = 6
# {:rectangle,2,3}
send pid, {:circle, 2}
#=> Площадь = 12.56
# {:circle,2}
# Кстати, интерактивная консоль — это тоже процесс.
# Чтобы узнать текущий PID, воспользуйтесь встроенной функцией `self`
self() #=> #PID<0.27.0>
```