Процесс
Удобства работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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 для построения своих систем и обращаются к этому модулю для получения информации, перехвата выходов, связей и мониторинга.
Обзор
Типы
- 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, не найден. Это может произойти, если таймер истек, был отменён или timer_ref никогда не соответствовал таймеру.
Даже если таймер истек, а сообщение было отправлено, эта функция не сообщает, пришло ли сообщение таймаута в пункт назначения.
Опции
-
:async- (логическое значение) приfalse, запрос на отмену синхронный. Приtrue, запрос асинхронный, т. е. запрос на отмену таймера выдан, и:okвозвращается сразу. По умолчаниюfalse. -
:info- (логическое значение) возвращать ли информацию об отмене таймера. Когда опция: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не ловит сигналы завершения, он завершится с заданным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.
Обратите внимание, что значения флагов :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() | {name :: atom(), node :: atom()} | name() :: atom()) ::
reference() Начинает мониторинг заданного item вызывающим процессом.
После завершения отслеживаемого процесса процесс мониторинга получает сообщение в виде:
{:DOWN, ref, :process, object, reason} где:
-
ref— ссылка на мониторинг, возвращённая этой функцией; -
object— либо PID отслеживаемого процесса (если отслеживается PID) или{name, node}(если отслеживается удалённое или локальное имя); -
reason— причина завершения.
Для примера см. the need for monitoring. Для получения дополнительной информации см. :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/Port отсутствует локально и не активен
- имя уже зарегистрировано
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- (булево) если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 задано, текущий процесс спит бесконечно и не потребляет и не отвечает на сообщения.
Используйте эту функцию с большой осторожностью. Почти во всех ситуациях, где вы бы использовали sleep/1 в Elixir, скорее всего, есть более правильный, быстрый и точный способ достижения того же результата с помощью обмена сообщениями.
Например, если вы ждете выполнения действия процессом, лучше сообщить о ходе выполнения такого действия с помощью сообщений.
Другими словами, не:
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.6.6/Process.html