Процесс
Удобства для работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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()
Назначение процесса.
Функции
- 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()
Specs
dest() ::
pid()
| port()
| (registered_name :: atom())
| {registered_name :: atom(), node()} Назначение процесса.
Удаленный или локальный PID, локальный порт, локально зарегистрированное имя или кортеж в формате {registered_name, node} для зарегистрированного имени на другом узле.
spawn_opt()
Specs
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()
Specs
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 не хранилось в словаре процесса.
Примеры
iex> Process.put(:comments, ["comment", "other comment"]) iex> Process.delete(:comments) ["comment", "other comment"] iex> Process.delete(:comments) nil
demonitor(monitor_ref, options \\ [])
Характеристики
demonitor(reference(), options :: [:flush | :info]) :: boolean()
Отключает мониторинг процесса, идентифицированного указанным reference.
Если monitor_ref является ссылкой, полученной вызывающим процессом с помощью вызова monitor/1, этот мониторинг отключается. Если мониторинг уже отключен, ничего не происходит.
См. :erlang.demonitor/2 для получения дополнительной информации.
Встроена в компилятор.
Примеры
pid = spawn(fn -> 1 + 2 end) ref = Process.monitor(pid) Process.demonitor(ref) #=> true
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(: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(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 не задано.
Примеры
# Assuming :locale was not set iex> Process.get(:locale, "pt") "pt" iex> Process.put(:locale, "fr") nil iex> Process.get(:locale, "pt") "fr"
get_keys()
Характеристики
get_keys() :: [term()]
Возвращает все ключи в словаре процесса.
Встроена в компилятор.
Примеры
# Assuming :locale was not set iex> :locale in Process.get_keys() false iex> Process.put(:locale, "pt") nil iex> :locale in Process.get_keys() true
get_keys(value)
Характеристики
get_keys(term()) :: [term()]
Возвращает все ключи в словаре процесса, которые имеют заданное значение value.
Встроена в компилятор.
group_leader()
Характеристики
group_leader() :: pid()
Возвращает PID лидера группы для вызывающего процесса.
Встроена в компилятор.
Примеры
Process.group_leader() #=> #PID<0.53.0>
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 для получения дополнительной информации.
Встроено компилятором.
Примеры
Process.list() #=> [#PID<0.0.0>, #PID<0.1.0>, #PID<0.2.0>, #PID<0.3.0>, ...]
monitor(item)
Характеристики
monitor(pid() | {name, node()} | name) :: reference() when name: atom() Начинает мониторинг заданного item из вызывающего процесса.
После того, как отслеживаемый процесс завершится, мониторинговому процессу передаётся сообщение в виде:
{:DOWN, ref, :process, object, reason} где:
-
ref— ссылка на мониторинг, возвращаемая этой функцией; -
object— это либоpidотслеживаемого процесса (если мониторится PID), либо{name, node}(если мониторится удалённое или локальное имя); -
reason— причина выхода.
Если процесс уже завершён во время вызова Process.monitor/1, сообщение :DOWN передаётся немедленно.
См. необходимость в мониторинге для примера. См. :erlang.monitor/2 для получения дополнительной информации.
Встроено компилятором.
Примеры
pid = spawn(fn -> 1 + 2 end)
#=> #PID<0.118.0>
Process.monitor(pid)
#=> #Reference<0.906660723.3006791681.40191>
Process.exit(pid, :kill)
#=> true
receive do
msg -> msg
end
#=> {:DOWN, #Reference<0.906660723.3006791681.40191>, :process, #PID<0.118.0>, :noproc} put(key, value)
Характеристики
put(term(), term()) :: term() | nil
Сохраняет заданную пару key-value в словаре процесса.
Значение, возвращаемое этой функцией, — это значение, которое ранее хранилось под key, или nil в случае отсутствия значения под ним.
Примеры
# Assuming :locale was not set iex> Process.put(:locale, "en") nil iex> 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
Примеры
Process.register(self(), :test) #=> true send(:test, :hello) #=> :hello send(:wrong_name, :hello) #=> ** (ArgumentError) argument error
registered()
Характеристики
registered() :: [atom()]
Возвращает список имён, которые были зарегистрированы с помощью register/2.
Встроено компилятором.
Примеры
Process.register(self(), :test) Process.registered() #=> [:test, :elixir_config, :inet_db, ...]
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 — атом, то это имя зарегистрированного процесса, которое находится в момент доставки. Ошибка не возникает, если имя не ссылается на процесс.
Сообщение не отправляется немедленно. Поэтому dest может получать другие сообщения между ними, даже когда time является 0.
Эта функция возвращает ссылку на таймер, который можно прочитать с помощью 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 # Optional timeout 30_000 -> :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
# Optional timeout
30_000 -> :timeout
end spawn(fun, opts)
Характеристики
spawn((() -> any()), spawn_opts()) :: pid() | {pid(), reference()} Запускает заданную функцию в соответствии с заданными параметрами.
Результат зависит от заданных параметров. В частности, если :monitor задан в качестве параметра, он вернёт кортеж, содержащий PID и ссылку на отслеживание, в противном случае — только PID запущенного процесса.
Доступно больше параметров; для получения полного списка доступных параметров см. :erlang.spawn_opt/4.
Встраивается компилятором.
Примеры
Process.spawn(fn -> 1 + 2 end, [:monitor])
#=> {#PID<0.93.0>, #Reference<0.18808174.1939079169.202418>}
Process.spawn(fn -> 1 + 2 end, [:link])
#=> #PID<0.95.0> 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 или порта.
Встраивается компилятором.
Примеры
Process.register(self(), :test) #=> true Process.unregister(:test) #=> true Process.unregister(:wrong_name) #=> ** (ArgumentError) argument error
whereis(name)
Характеристики
whereis(atom()) :: pid() | port() | nil
Возвращает идентификатор PID или порта, зарегистрированный под name или nil, если имя не зарегистрировано.
Для получения дополнительной информации см. :erlang.whereis/1.
Примеры
Process.register(self(), :test) Process.whereis(:test) #=> #PID<0.84.0> Process.whereis(:wrong_name) #=> nil
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.9.4/Process.html