summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEv Bogdanov <evbogdanov.com@gmail.com>2017-08-19 21:55:53 +0300
committerEv Bogdanov <evbogdanov.com@gmail.com>2017-08-19 21:55:53 +0300
commit13a89c7fd0a593876ad4366d4c89182612b76db6 (patch)
treefd195279319a5170a0461538a1ffb6fdd789b0aa
parentb4d50ee299ca4d14238f58225e0ddfdf98876eaa (diff)
[elixir/ru] Concurrency
-rw-r--r--ru-ru/elixir-ru.html.markdown56
1 files changed, 56 insertions, 0 deletions
diff --git a/ru-ru/elixir-ru.html.markdown b/ru-ru/elixir-ru.html.markdown
index 6fb176ab..459df53e 100644
--- a/ru-ru/elixir-ru.html.markdown
+++ b/ru-ru/elixir-ru.html.markdown
@@ -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>
+
```