Процесс
Удобства для работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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
Хотя этот модуль предоставляет удобства низкого уровня для работы с процессами, разработчики обычно используют абстракции, такие как Agent, GenServer, Registry, Supervisor и Task для построения своих систем и прибегают к этому модулю для сбора информации, перехвата выходов, связей и мониторинга.
Краткое описание
Типы
- dest()
-
Назначение процесса
- 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)
-
Отправляет сообщение заданному
dest - 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, если имя не зарегистрировано
Типы
dest()
dest() ::
pid() | port() | registered_name() ::
atom() | {registered_name :: atom(), node()} Назначение процесса.
Удаленный или локальный PID, локальный порт, локально зарегистрированное имя или кортеж в форме {registered_name, node} для зарегистрированного имени на другом узле.
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 должен ссылаться на процесс, выполняемый на локальном узле, иначе будет поднято исключение ArgumentError.
Встраивается компилятором.
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, не найден. Это может произойти, либо потому, что таймер истек, либо потому, что он уже был отменен, либо потому, что 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(:trap_exit, boolean()) :: boolean()
flag(:sensitive, boolean()) :: boolean()
flag(:save_calls, 0..10000) :: 0..10000
flag(:priority, priority_level()) :: priority_level()
flag({:monitor_nodes, term()}, term()) :: term()
flag(:monitor_nodes, term()) :: term()
flag(:min_heap_size, non_neg_integer()) :: non_neg_integer()
flag(:min_bin_vheap_size, non_neg_integer()) :: non_neg_integer()
flag(:message_queue_data, :erlang.message_queue_data()) :: :erlang.message_queue_data()
flag(:max_heap_size, heap_size()) :: heap_size()
flag(:error_handler, module()) :: module()
Устанавливает заданный flag в value для вызывающего процесса.
Возвращает старое значение flag.
См. :erlang.process_flag/2 для получения дополнительной информации.
Встроен в компилятор.
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() | nil
Возвращает информацию о процессе, идентифицированном 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() | {name :: atom(), node :: atom()} | name() :: atom()) ::
reference() Начинает мониторинг заданного item со стороны вызывающего процесса.
После того, как отслеживаемый процесс завершит работу, мониторинговому процессу будет передано сообщение в форме:
{:DOWN, ref, :process, object, reason} где:
-
ref— ссылка на мониторинг, возвращаемая этой функцией; -
object— это либо PID отслеживаемого процесса (если мониторится PID) или{name, node}(если мониторится удалённое или локальное имя); -
reason— причина завершения.
Если процесс уже завершил работу при вызове Process.monitor/1, сообщение :DOWN передаётся немедленно.
См. нужда в мониторинге для примера. См. :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.
pid_or_port должно быть атомом и может использоваться вместо идентификатора 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: dest(), msg: any(), option: :noconnect | :nosuspend
Отправляет сообщение заданному dest.
dest может быть удалённым или локальным PID, локальным портом, локально зарегистрированным именем или кортежем в форме {registered_name, node} для зарегистрированного имени на другом узле.
Встраивается компилятором.
Параметры
-
: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— (логический) когда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.7.4/Process.html