Процесс
Удобства для работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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/0Kernel.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не ловит сигналы завершения, процесс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(: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). Предположим, что процесс A и процесс B связаны. Если процесс A завершается по причине, отличной от нормального завершения (которая также является причиной завершения, когда процесс завершает свою работу) и процесс B не отслеживает завершения (см. flag/2), тогда процесс B завершится с той же причиной, что и процесс A, и, в свою очередь, отправит сигнал завершения всем своим другим связанным процессам. Поведение, когда процесс B отслеживает завершения, описано в 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() Начинает отслеживание заданного объекта (PID, порта или имени) из вызывающего процесса.
Когда отслеживаемый процесс завершается, процессу, который производит отслеживание, передаётся сообщение в виде:
``` {monitor, Ref, Reason} ```где:
- Ref — это ссылка на монитор, возвращённая этой функцией;
- Reason — это либо причина завершения отслеживаемого процесса (если отслеживается PID), либо причина завершения (если отслеживается удалённое или локальное имя);
- Reason — причина завершения.
Если процесс уже завершен при вызове Process.monitor/1, сразу передаётся сообщение `reason`.
См. необходимость мониторинга для примера. См. :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
Сохраняет заданную пару ключ-значение в словаре процесса.
Значением возврата этой функции является значение, которое ранее хранилось по этому ключу, или `undefined`, в случае, если по нему не хранилось никаких значений.
Примеры
# 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.
Если результат — целое число, оно представляет время в миллисекундах, оставшееся до истечения таймера.
Если результат — `undefined`, таймер, соответствующий заданной ссылке, не найден. Это может быть связано с тем, что таймер истек, был отменён или заданная ссылка никогда не соответствовала таймеру.
Даже если таймер истек, а сообщение было отправлено, эта функция не сообщает, прибыло ли сообщение о таймауте к месту назначения.
Встроенная компилятором.
register(pid_or_port, name)
Характеристики
register(pid() | port(), atom()) :: true
Регистрирует заданный процесс или порт под заданным именем.
Имя должно быть атомом и может использоваться вместо идентификатора PID/порта при отправке сообщений с помощью Kernel.send/2.
register/2 завершится ошибкой `badarg` в следующих случаях:
- PID/порт не существует локально и не активен
- Имя уже зарегистрировано
- Этот PID/порт уже зарегистрирован под другим именем
Следующие имена зарезервированы и не могут быть присвоены процессам или портам:
nilfalsetrue: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
Отправляет сообщение заданному объекту.
Объект может быть удалённым или локальным PID, локальным портом, локально зарегистрированным именем или кортежем в формате `{remote, Name}` для зарегистрированного имени на другом узле.
Встроенная компилятором.
Параметры
`{async, true}` — при использовании, если отправка сообщения требует автоматического подключения к другому узлу, сообщение не отправляется, и возвращается `error`.
`{sync, true}` — при использовании, если отправка сообщения приведет к приостановке отправителя, сообщение не отправляется, и возвращается `error`.
В противном случае сообщение отправляется, и возвращается `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()} Отправляет сообщение в заданный объект через заданное количество миллисекунд.
Если `dest` — это PID, то это PID локального процесса, завершённого или активного. Если `dest` — атом, то это имя зарегистрированного процесса, которое ищется во время доставки. Ошибка не возникает, если имя не ссылается на процесс.
Сообщение не отправляется сразу. Поэтому процесс `dest` может получать другие сообщения между отправкой, даже когда `dest` является активным.
Эта функция возвращает ссылку на таймер, которую можно прочитать с помощью read_timer/1 или отменить с помощью cancel_timer/1.
Таймер будет автоматически отменён, если заданный `dest` — это PID, который не активен, или когда заданный PID завершается. Обратите внимание, что таймеры не будут автоматически отменены, когда `dest` — это атом (так как разрешение атома выполняется при доставке).
Встроенная компилятором.
Параметры
-
`{absolute, true/false}` — (булево) когда `true`, `time` обрабатывается как относительное к текущему монотонному времени. Когда `false`, `time` — абсолютное значение эрлангового монотонного времени, в котором сообщение должно быть доставлено в `dest`. Для получения дополнительной информации об эрланговом монотонном времени и других концепциях, связанных со временем, см. документацию для модуля
System. По умолчанию `false`.
Примеры
timer_ref = Process.send_after(pid, :hi, 1000)
sleep(timeout)
Характеристики
sleep(timeout()) :: :ok
Приостанавливает текущий процесс на заданный интервал.
Аргумент `timeout` — это либо количество миллисекунд для сна в виде целого числа, либо атом `infinity`. Когда `timeout` задан как `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 # 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` не существует, эта функция не генерирует ошибок и просто ничего не делает.
Значение возврата этой функции всегда `ok`.
См. :erlang.unlink/1 для получения дополнительной информации.
Встроено компилятором.
unregister(name)
Характеристики
unregister(atom()) :: true
Удаляет зарегистрированное имя, связанное с идентификатором 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 или порта, зарегистрированный под указанным именем. Возвращает `undefined` или `nomatch`, если имя не зарегистрировано.
См. :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.10.4/Process.html