Процессы
Удобства работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль Kernel экспонирует и автоматически импортирует некоторые базовые функциональные возможности, связанные с процессами, доступные через следующие функции:
-
Kernel.spawn/1иKernel.spawn/3 -
Kernel.spawn_link/1иKernel.spawn_link/3 -
Kernel.spawn_monitor/1иKernel.spawn_monitor/3 -
Kernel.self/0 -
Kernel.send/2
Краткое описание
Типы
- spawn_opt()
- spawn_opts()
Функции
- alive?(pid)
-
Определяет, жив ли данный процесс
- cancel_timer(timer_ref, options \\ [])
-
Отменяет таймер, возвращённый функцией
send_after/3 - delete(key)
-
Удаляет указанный
keyиз словаря процессов - demonitor(monitor_ref, options \\ [])
-
Отключает мониторинг процесса, идентифицируемого данным
reference - exit(pid, reason)
-
Отправляет сигнал завершения с заданным
reasonпроцессуpid - flag(flag, value)
-
Устанавливает заданное
flagвvalueдля вызывающего процесса - flag(pid, flag, value)
-
Устанавливает заданное
flagвvalueдля заданного процессаpid - get()
-
Возвращает все пары ключ-значение в словаре процессов
- get(key, default \\ nil)
-
Возвращает значение для заданного
keyв словаре процессов илиdefault, еслиkeyне задан - get_keys()
-
Возвращает все ключи в словаре процессов
- get_keys(value)
-
Возвращает все ключи в словаре процессов, имеющие заданное значение
value - group_leader()
-
Возвращает PID лидера группы для вызывающего процесса
- group_leader(pid, leader)
-
Устанавливает лидера группы для данного
pidвleader - hibernate(mod, fun_name, args)
-
Переводит вызывающий процесс в состояние «спячки»
- info(pid)
-
Возвращает информацию о процессе, идентифицируемом
pid, илиnil, если процесс не жив - info(pid, spec)
-
Возвращает информацию о процессе, идентифицируемом
pid, илиnil, если процесс не жив - link(pid_or_port)
-
Создаёт связь между вызывающим процессом и заданным элементом (процесс или порт)
- list()
-
Возвращает список PID, соответствующих всем процессам, которые в данный момент существуют на локальном узле
- monitor(item)
-
Начинает мониторинг заданного
itemвызывающим процессом - put(key, value)
-
Сохраняет заданную пару
key-valueв словаре процессов - read_timer(timer_ref)
-
Читает таймер, созданный функцией
send_after/3 - register(pid_or_port, name)
-
Регистрирует заданный
pid_or_portпод заданнымname - registered()
-
Возвращает список имён, зарегистрированных с помощью
register/2 - send(dest, msg, options)
-
Отправляет сообщение заданному процессу
- send_after(dest, msg, time, opts \\ [])
-
Отправляет
msgпроцессуdestчерезtimeмиллисекунд - sleep(timeout)
-
Заставляет текущий процесс спать в течение заданного
timeout - spawn(fun, opts)
-
Создаёт дочерний процесс заданной функции в соответствии с заданными параметрами
- spawn(mod, fun, args, opts)
-
Создаёт дочерний процесс заданной функции
funиз модуляmod, передавая заданныеargsв соответствии с заданными параметрами - unlink(pid_or_port)
-
Удаляет связь между вызывающим процессом и заданным элементом (процесс или порт)
- unregister(name)
-
Удаляет зарегистрированное
name, связанное с PID или идентификатором порта - whereis(name)
-
Возвращает PID или идентификатор порта, зарегистрированный под
name, илиnil, если имя не зарегистрировано
Типы
spawn_opt()
spawn_opt() ::
:link |
:monitor |
{:priority, :low | :normal | :high} |
{:fullsweep_after, non_neg_integer()} |
{:min_heap_size, non_neg_integer()} |
{:min_bin_vheap_size, non_neg_integer()} spawn_opts()
spawn_opts() :: [spawn_opt()]
Функции
alive?(pid)
alive?(pid()) :: boolean()
Определяет, жив ли указанный процесс.
Если процесс, идентифицируемый pid, жив (то есть он не завершается и ещё не завершился), эта функция возвращает true. В противном случае она возвращает false.
pid должен ссылаться на процесс, запущенный на локальном узле.
Встроен компилятором.
cancel_timer(timer_ref, options \\ [])
cancel_timer(reference(), options) :: non_neg_integer() | false | :ok when options: [async: boolean(), info: boolean()]
Отменяет таймер, возвращённый функцией send_after/3.
Если результат — целое число, оно представляет время в миллисекундах, оставшееся до истечения таймера.
Если результат — false, таймер, соответствующий timer_ref, не найден. Это может произойти, если таймер истек, был отменён или никогда не соответствовал таймеру.
Даже если таймер истек, а сообщение было отправлено, эта функция не сообщает, пришло ли сообщение о таймауте в пункт назначения.
Параметры
-
:async- (boolean) еслиfalse, запрос на отмену синхронный. Еслиtrue, запрос на отмену асинхронный, что означает, что запрос на отмену таймера отправлен, и:okвозвращается сразу. По умолчаниюfalse. -
:info- (boolean) возвращать ли информацию об отмене таймера. Если параметр:asyncравенfalse, и:infoравенtrue, возвращается целое число илиfalse. Если:asyncравенfalse, и:infoравенfalse, возвращается:ok. Если:asyncравенtrue, и:infoравенtrue, при выполнении отмены вызывающему процессу отправляется сообщение в формате{:cancel_timer, timer_ref, result}, гдеresult— целое число илиfalse. Если:asyncравенtrue, и:infoравенfalse, никакого сообщения не отправляется. По умолчаниюtrue.
Встроен компилятором.
delete(key)
delete(term()) :: term() | nil
Удаляет указанный key из словаря процессов.
Возвращает значение, которое было под key в словаре процессов, или nil, если key не хранилось в словаре.
Примеры
Process.put(:comments, ["comment", "other comment"]) Process.delete(:comments) #=> ["comment", "other comment"] Process.delete(:comments) #=> nil
demonitor(monitor_ref, options \\ [])
demonitor(reference(), options :: [:flush | :info]) :: boolean()
Отключает мониторинг процесса, идентифицируемого данным reference.
Если monitor_ref — ссылка, полученная вызывающим процессом при вызове monitor/1, этот мониторинг отключается. Если мониторинг уже отключен, ничего не происходит.
См. :erlang.demonitor/2 для более подробной информации.
Встроен компилятором.
exit(pid, reason)
exit(pid(), term()) :: true
Отправляет сигнал завершения с заданным reason процессу pid.
Следующее поведение применяется, если reason — любой термин, кроме :normal или :kill:
-
Если
pidне перехватывает выходы,pidзавершится с заданнымreason. -
Если
pidперехватывает выходы, сигнал выхода преобразуется в сообщение{:EXIT, from, reason}и доставляется в очередь сообщенийpid.
Если reason — атом :normal, pid не завершится (если только pid не является вызывающим процессом, в этом случае он завершится с причиной :normal). Если процесс перехватывает выходы, сигнал выхода преобразуется в сообщение {:EXIT, from, :normal} и доставляется в его очередь сообщений.
Если reason — атом :kill, то есть если Process.exit(pid, :kill) вызывается, непоймаемый сигнал выхода отправляется pid, который безусловно завершит работу с причиной :killed.
Вставлено компилятором.
Примеры
Process.exit(pid, :kill) #=> true
flag(flag, value)
flag(:error_handler, module()) :: module()
flag(:max_heap_size, heap_size()) :: heap_size()
flag(:message_queue_data, :erlang.message_queue_data()) :: :erlang.message_queue_data()
flag(:min_bin_vheap_size, non_neg_integer()) :: non_neg_integer()
flag(:min_heap_size, non_neg_integer()) :: non_neg_integer()
flag(:monitor_nodes, term()) :: term()
flag({:monitor_nodes, term()}, term()) :: term()
flag(:priority, priority_level()) :: priority_level()
flag(:save_calls, 0..10000) :: 0..10000
flag(:sensitive, boolean()) :: boolean()
flag(:trap_exit, boolean()) :: boolean()
Устанавливает заданный flag в value для вызывающего процесса.
Возвращает старое значение flag.
См. :erlang.process_flag/2 для получения дополнительной информации.
Обратите внимание, что значения флагов flag :max_heap_size и :message_queue_data доступны только начиная с OTP 19.
Вставлено компилятором.
flag(pid, flag, value)
flag(pid(), :save_calls, 0..10000) :: 0..10000
Устанавливает заданный flag в value для заданного процесса pid.
Возвращает старое значение flag.
Возвышает исключение ArgumentError, если pid не является локальным процессом.
Разрешенные значения для flag — это только подмножество значений, разрешенных в flag/2, а именно :save_calls.
См. :erlang.process_flag/3 для получения дополнительной информации.
Вставлено компилятором.
get()
get() :: [{term(), term()}] Возвращает все пары ключ-значение в словаре процесса.
Вставлено компилятором.
get(key, default \\ nil)
get(term(), default :: term()) :: term()
Возвращает значение для данного key в словаре процесса или default, если key не задано.
get_keys()
get_keys() :: [term()]
Возвращает все ключи в словаре процесса.
Вставлено компилятором.
get_keys(value)
get_keys(term()) :: [term()]
Возвращает все ключи в словаре процесса, имеющие данное value.
Вставлено компилятором.
group_leader()
group_leader() :: pid()
Возвращает PID лидера группы для вызывающего процесса.
Вставлено компилятором.
group_leader(pid, leader)
group_leader(pid(), leader :: pid()) :: true
Устанавливает лидера группы для данного pid в leader.
Обычно используется, когда процесс, запущенный из определенной оболочки, должен иметь лидера группы, отличного от :init.
Вставлено компилятором.
hibernate(mod, fun_name, args)
hibernate(module(), atom(), list()) :: no_return()
Переводит вызывающий процесс в состояние «спячки».
Вызывающий процесс переводится в состояние ожидания, где его выделение памяти уменьшено по возможности, что полезно, если процесс не ожидает получения сообщений в ближайшем будущем.
См. :erlang.hibernate/3 для получения дополнительной информации.
Вставлено компилятором.
info(pid)
info(pid()) :: keyword()
Возвращает информацию о процессе, идентифицированном по pid, или возвращает nil, если процесс не активен.
Используйте только для отладочной информации.
См. :erlang.process_info/1 для получения дополнительной информации.
info(pid, spec)
info(pid(), atom() | [atom()]) ::
{atom(), term()} |
[{atom(), term()}] |
nil Возвращает информацию о процессе, идентифицированном по pid, или возвращает nil, если процесс не активен.
См. :erlang.process_info/2 для получения дополнительной информации.
link(pid_or_port)
link(pid() | port()) :: true
Создает связь между вызывающим процессом и заданным элементом (процессом или портом).
Связи двусторонние. Связанные процессы можно разъединить, используя unlink/1.
Если такая связь уже существует, эта функция ничего не делает, так как между двумя заданными процессами может быть только одна связь. Если процесс пытается создать связь с самим собой, ничего не произойдет.
Когда два процесса связаны, каждый из них получает сигналы выхода от другого (см. также exit/2). Предположим, что pid1 и pid2 связаны. Если pid2 завершается с причиной, отличной от :normal (это также причина завершения, когда процесс завершает свою работу), и pid1 не перехватывает выходы (см. flag/2), то pid1 завершится с той же причиной, что и pid2, и, в свою очередь, отправит сигнал выхода всем своим другим связанным процессам. Поведение, когда pid1 перехватывает выходы, описано в exit/2.
См. :erlang.link/1 для получения дополнительной информации.
Вставлено компилятором.
list()
list() :: [pid()]
Возвращает список PID, соответствующих всем процессам, которые в данный момент существуют на локальном узле.
Обратите внимание, что если процесс завершается, он считается существующим, но не активным. Это означает, что для такого процесса alive?/1 вернет false, но его PID будет частью списка PID, возвращаемых этой функцией.
См. :erlang.processes/0 для получения дополнительной информации.
Вставлено компилятором.
monitor(item)
monitor(pid() | {reg_name :: atom(), node :: atom()} | reg_name() :: atom()) :: reference() Начинает отслеживание заданного item из вызывающего процесса.
После того, как отслеживаемый процесс завершится, в процесс отслеживания доставляется сообщение в формате:
{:DOWN, ref, :process, object, reason} где:
-
ref— ссылка на монитор, возвращаемая этой функцией; -
object— либоpidотслеживаемого процесса (если отслеживается PID), либо{name, node}(если отслеживается удалённое или локальное имя); -
reason— причина завершения.
См. потребность в мониторинге для примера. См. :erlang.monitor/2 для получения дополнительной информации.
Вставлено компилятором.
put(key, value)
put(term(), term()) :: term() | nil
Сохраняет заданную пару key-value в словаре процесса.
Значение возвращаемой функцией — значение, которое ранее хранилось под key, или nil в случае отсутствия значения под key.
Примеры
# Assuming :locale was not set Process.put(:locale, "en") #=> nil Process.put(:locale, "fr") #=> "en"
read_timer(timer_ref)
read_timer(reference()) :: non_neg_integer() | false
Читает таймер, созданный с помощью send_after/3.
Когда результатом является целое число, оно представляет время в миллисекундах, оставшееся до истечения таймера.
Когда результатом является false, таймер, соответствующий timer_ref, не найден. Это может быть из-за истечения таймера, его отмены или того, что timer_ref никогда не соответствовал таймеру.
Даже если таймер истек, а сообщение было отправлено, эта функция не сообщает вам, пришло ли сообщение о таймауте в пункт назначения.
Вставлено компилятором.
register(pid_or_port, name)
register(pid() | port(), atom()) :: true
Регистрирует заданный pid_or_port под заданным name.
name должен быть атомом и может затем использоваться вместо идентификатора PID/порта при отправке сообщений с помощью Kernel.send/2.
register/2 завершится с ошибкой ArgumentError в любом из следующих случаев:
- PID/Порт не существует локально и не активен
- Имя уже зарегистрировано
pid_or_portуже зарегистрировано под другимname
Следующие имена зарезервированы и не могут быть назначены процессам или портам:
-
nil -
false -
true -
:undefined
registered()
registered() :: [atom()]
Возвращает список имён, зарегистрированных с помощью register/2.
Вставлено компилятором.
send(dest, msg, options)
send(dest, msg, [option]) ::
:ok |
:noconnect |
:nosuspend when dest: pid() | port() | atom() | {atom(), node()}, msg: any(), option: :noconnect | :nosuspend Отправляет сообщение заданному процессу.
Параметры
-
:noconnect— при использовании, если отправка сообщения требует автоматического подключения к другому узлу, сообщение не отправляется, и возвращается:noconnect. -
:nosuspend— при использовании, если отправка сообщения приведет к приостановке отправителя, сообщение не отправляется, и возвращается:nosuspend.
В противном случае сообщение отправляется, и возвращается :ok.
Примеры
iex> Process.send({:name, :node_that_does_not_exist}, :hi, [:noconnect])
:noconnect Вставлено компилятором.
send_after(dest, msg, time, opts \\ [])
send_after(pid() | atom(), term(), non_neg_integer(), [option]) :: reference() when option: {:abs, boolean()} Отправляет msg процессу dest через time миллисекунд.
Если dest — это идентификатор процесса (PID), он должен быть PID локального процесса, живого или завершённого. Если dest — это атом, он должен быть именем зарегистрированного процесса, который ищется в момент доставки. Ошибка не генерируется, если имя не ссылается на процесс.
Эта функция возвращает ссылку на таймер, который можно считать с помощью read_timer/1 или отменить с помощью cancel_timer/1.
Таймер будет автоматически отменён, если заданный dest — это PID неактивного процесса или когда процесс с данным PID завершается. Обратите внимание, что таймеры не отменяются автоматически, когда dest — это атом (так как разрешение атома выполняется при доставке).
Встроенная компилятором.
Параметры
-
:abs- (boolean) когдаfalse,timeрассматривается как относительное значение к текущему монотонному времени. Когдаtrue,time— это абсолютное значение монотонного времени Erlang, в котороеmsgдолжно быть доставленоdest. Для получения дополнительной информации о монотонном времени Erlang и других связанных с временем понятиях, см. документацию модуляSystem. Значение по умолчанию —false.
Примеры
timer_ref = Process.send_after(pid, :hi, 1000)
sleep(timeout)
sleep(timeout()) :: :ok
Приостанавливает текущий процесс на заданное timeout.
timeout — это количество миллисекунд, на которые необходимо приостановить процесс в виде целого числа, или атом :infinity. Если :infinity задан, текущий процесс будет приостановлен навсегда и не будет потреблять сообщения или отвечать на них.
Используйте эту функцию с большой осторожностью. Практически во всех ситуациях, где в Elixir вы бы использовали sleep/1, скорее всего, есть более правильный, быстрый и точный способ достижения того же с помощью передачи сообщений.
Например, если вы ждёте, пока процесс выполнит какое-либо действие, лучше сообщить о ходе этого действия с помощью сообщений.
Другими словами, не:
Task.start_link fn -> do_something() ... end # Wait until work is done Process.sleep(2000)
Но делайте:
parent = self() Task.start_link fn -> do_something() send parent, :work_is_done ... end receive do :work_is_done -> :ok after 30_000 -> :timeout # Optional timeout end
В таких случаях, как описанный выше, предпочтительны Task.async/1 и Task.await/2.
Аналогично, если вы ждёте завершения процесса, отслеживайте этот процесс вместо приостановки. Не:
Task.start_link fn -> ... end # Wait until task terminates Process.sleep(2000)
Вместо этого делайте:
{:ok, pid} =
Task.start_link fn ->
...
end
ref = Process.monitor(pid)
receive do
{:DOWN, ^ref, _, _, _} -> :task_is_down
after
30_000 -> :timeout # Optional timeout
end spawn(fun, opts)
spawn((() -> any()), spawn_opts()) :: pid() | {pid(), reference()} Запускает заданную функцию в соответствии с заданными параметрами.
Результат зависит от заданных параметров. В частности, если :monitor задан как параметр, он вернёт кортеж, содержащий PID и ссылку на мониторинг, в противном случае только PID запущенного процесса.
Доступно больше параметров; для полного списка доступных параметров см. :erlang.spawn_opt/4.
Встроенная компилятором.
spawn(mod, fun, args, opts)
spawn(module(), atom(), list(), spawn_opts()) ::
pid() |
{pid(), reference()} Запускает заданную функцию fun из модуля mod, передавая заданные args в соответствии с заданными параметрами.
Результат зависит от заданных параметров. В частности, если :monitor задан как параметр, он вернёт кортеж, содержащий PID и ссылку на мониторинг, в противном случае только PID запущенного процесса.
Также принимает дополнительные параметры; для списка доступных параметров см. :erlang.spawn_opt/4.
Встроенная компилятором.
unlink(pid_or_port)
unlink(pid() | port()) :: true
Удаляет связь между вызывающим процессом и заданным элементом (процессом или портом).
Если такой связи нет, функция ничего не делает. Если pid_or_port не существует, функция не генерирует ошибок и просто ничего не делает.
Значение возврата этой функции всегда true.
См. :erlang.unlink/1 для получения дополнительной информации.
Встроенная компилятором.
unregister(name)
unregister(atom()) :: true
Удаляет зарегистрированное name, связанное с идентификатором PID или порта.
Возвращает ошибку ArgumentError, если имя не зарегистрировано для любого PID или порта.
Встроенная компилятором.
whereis(name)
whereis(atom()) :: pid() | port() | nil
Возвращает идентификатор PID или порта, зарегистрированный под name, или nil, если имя не зарегистрировано.
См. :erlang.whereis/1 для получения дополнительной информации.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.5.3/Process.html