Процесс
Удобства для работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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()Source
@type dest() ::
pid()
| port()
| (registered_name :: atom())
| {registered_name :: atom(), node()} Назначение процесса.
Удаленный или локальный PID, локальный порт, локально зарегистрированное имя или кортеж в форме {registered_name, node} для зарегистрированного имени на другом узле.
spawn_opt()Source
@type spawn_opt() ::
:link
| :monitor
| {:monitor, monitor_option()}
| {:priority, :low | :normal | :high}
| {:fullsweep_after, non_neg_integer()}
| {:min_heap_size, non_neg_integer()}
| {:min_bin_vheap_size, non_neg_integer()}
| {:max_heap_size, heap_size()}
| {:message_queue_data, :off_heap | :on_heap} spawn_opts()Source
@type spawn_opts() :: [spawn_opt()]
Функции
alive?(pid)Source
@spec alive?(pid()) :: boolean()
Определяет, является ли данный процесс активным на локальном узле.
Если процесс, идентифицируемый pid жив (то есть он не завершается и еще не завершился), то эта функция возвращает true. В противном случае она возвращает false.
pid должен ссылаться на процесс, запущенный на локальном узле, иначе будет поднята ошибка ArgumentError.
Встроено компилятором.
cancel_timer(timer_ref, options \\ [])Source
@spec cancel_timer(reference(), options) :: non_neg_integer() | false | :ok when options: [async: boolean(), info: boolean()]
Отменяет таймер, возвращённый функцией send_after/3.
Если результат — целое число, оно представляет время в миллисекундах, оставшееся до истечения таймера.
Если результат — false, таймер, соответствующий 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)Source
@spec 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 \\ [])Source
@spec 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)Source
@spec 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)Source
@spec flag(:error_handler, module()) :: module()
@spec flag(:max_heap_size, heap_size()) :: heap_size()
@spec flag(:message_queue_data, :off_heap | :on_heap) :: :off_heap | :on_heap
@spec flag(:min_bin_vheap_size, non_neg_integer()) :: non_neg_integer()
@spec flag(:min_heap_size, non_neg_integer()) :: non_neg_integer()
@spec flag(:priority, priority_level()) :: priority_level()
@spec flag(:save_calls, 0..10000) :: 0..10000
@spec flag(:sensitive, boolean()) :: boolean()
@spec flag(:trap_exit, boolean()) :: boolean()
Устанавливает заданный flag в value для вызывающего процесса.
Возвращает старое значение flag.
См. :erlang.process_flag/2 для получения дополнительной информации.
Встроено компилятором.
flag(pid, flag, value)Source
@spec flag(pid(), :save_calls, 0..10000) :: 0..10000
Устанавливает заданный flag в value для заданного процесса pid.
Возвращает старое значение flag.
Вызывает ошибку ArgumentError, если pid не является локальным процессом.
Допустимые значения для flag — только подмножество значений, допустимых в flag/2, а именно :save_calls.
См. :erlang.process_flag/3 для получения дополнительной информации.
Встроено компилятором.
get()Source
@spec get() :: [{term(), term()}] Возвращает все пары ключ-значение в словаре процесса.
Встроено компилятором.
get(key, default \\ nil)Source
@spec 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()Source
@spec 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)Source
@spec get_keys(term()) :: [term()]
Возвращает все ключи в словаре процесса, которые имеют заданное value.
Встроено компилятором.
group_leader()Source
@spec group_leader() :: pid()
Возвращает PID лидера группы для вызывающего процесса.
Встроено компилятором.
Примеры
Process.group_leader() #=> #PID<0.53.0>
group_leader(pid, leader)Source
@spec group_leader(pid(), leader :: pid()) :: true
Устанавливает лидера группы для заданного pid в leader.
Обычно используется, когда процесс, запущенный из определённой оболочки, должен иметь лидера группы отличного от :init.
Встроено компилятором.
hibernate(mod, fun_name, args)Source
@spec hibernate(module(), atom(), list()) :: no_return()
Переводит вызывающий процесс в состояние «спячки».
Вызывающий процесс переводится в состояние ожидания, при этом выделение памяти для него сводится к минимуму. Это полезно, если процесс не ожидает получить какие-либо сообщения в ближайшем будущем.
См. :erlang.hibernate/3 для получения дополнительной информации.
Встраивается компилятором.
info(pid)Source
@spec info(pid()) :: keyword() | nil
Возвращает информацию о процессе, идентифицированном по pid, или возвращает nil, если процесс не активен.
Используйте эту функцию только для отладки.
См. :erlang.process_info/1 для получения дополнительной информации.
info(pid, spec)Source
@spec info(pid(), atom() | [atom()]) :: {atom(), term()} | [{atom(), term()}] | nil Возвращает информацию о процессе, идентифицированном по pid, или возвращает nil, если процесс не активен.
См. :erlang.process_info/2 для получения дополнительной информации.
link(pid_or_port)Source
@spec link(pid() | port()) :: true
Создает связь между вызывающим процессом и заданным элементом (процессом или портом).
Связи двунаправленные. Связанные процессы могут быть разъединены с помощью unlink/1.
Если такая связь уже существует, эта функция ничего не делает, так как между двумя заданными процессами может быть только одна связь. Если процесс пытается установить связь с самим собой, ничего не произойдёт.
Когда два процесса связаны, каждый из них получает сигналы выхода от другого (см. также exit/2). Предположим, pid1 и pid2 связаны. Если pid2 завершается по причине, отличной от :normal (которая также является причиной завершения, когда процесс завершает свою работу), и pid1 не перехватывает выходы (см. flag/2), то pid1 завершится по той же причине, что и pid2 и, в свою очередь, отправит сигнал выхода всем своим другим связанным процессам. Поведение, когда pid1 перехватывает выходы, описано в exit/2.
См. :erlang.link/1 для получения дополнительной информации.
Встраивается компилятором.
list()Source
@spec list() :: [pid()]
Возвращает список идентификаторов процессов (PID), соответствующих всем процессам, которые в данный момент существуют на локальном узле.
Обратите внимание, что если процесс завершается, он считается существующим, но не активным. Это означает, что для такого процесса alive?/1 вернет false, но его PID будет частью списка PID, возвращаемого этой функцией.
Встраивается компилятором.
Примеры
Process.list() #=> [#PID<0.0.0>, #PID<0.1.0>, #PID<0.2.0>, #PID<0.3.0>, ...]
monitor(item)Source
@spec 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 передаётся немедленно.
См. "The need for monitoring" для примера. См. :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)Source
@spec 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)Source
@spec read_timer(reference()) :: non_neg_integer() | false
Считывает таймер, созданный с помощью send_after/3.
Если результат — целое число, оно представляет время в миллисекундах, оставшееся до истечения таймера.
Если результат — false, таймер, соответствующий timer_ref, не найден. Это может быть связано с истечением таймера, его отменением или с тем, что timer_ref никогда не соответствовал таймеру.
Даже если таймер истек и сообщение было отправлено, эта функция не сообщает вам, достигло ли сообщение о таймауте своего назначения.
Встраивается компилятором.
register(pid_or_port, name)Source
@spec register(pid() | port(), atom()) :: true
Регистрирует заданный pid_or_port под заданным name.
name должен быть атомом и может быть использован вместо идентификатора PID/порта при отправке сообщений с помощью Kernel.send/2.
register/2 завершится ошибкой ArgumentError в следующих случаях:
- PID/порт не существует локально и не активен
- имя уже зарегистрировано
pid_or_portуже зарегистрирован под другимname
Следующие имена зарезервированы и не могут быть назначены процессам или портам:
nilfalsetrue:undefined
Примеры
Process.register(self(), :test) #=> true send(:test, :hello) #=> :hello send(:wrong_name, :hello) ** (ArgumentError) argument error
registered()Source
@spec registered() :: [atom()]
Возвращает список имен, зарегистрированных с помощью register/2.
Встраивается компилятором.
Примеры
Process.register(self(), :test) Process.registered() #=> [:test, :elixir_config, :inet_db, ...]
send(dest, msg, options)Source
@spec 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 \\ [])Source
@spec 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- (boolean) когдаfalse,timeобрабатывается как относительное значение к текущему монотонному времени. Когдаtrue,time— абсолютное значение монотонного времени Erlang, в котороеmsgдолжно быть доставлено вdest. Чтобы узнать больше о монотонном времени Erlang и других связанных с временем понятиях, см. документацию модуляSystem. По умолчаниюfalse.
Примеры
timer_ref = Process.send_after(pid, :hi, 1000)
sleep(timeout)Source
@spec 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)Source
@spec 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)Source
@spec spawn(module(), atom(), list(), spawn_opts()) :: pid() | {pid(), reference()} Запускает заданную функцию fun из модуля mod, передавая заданные args в соответствии с заданными параметрами.
Результат зависит от заданных параметров. В частности, если :monitor указан в качестве параметра, возвращается кортеж, содержащий PID и ссылку на мониторинг, иначе только PID запущенного процесса.
Также принимаются дополнительные параметры; для списка доступных параметров см. :erlang.spawn_opt/4.
Встраивается компилятором.
unlink(pid_or_port)Source
@spec unlink(pid() | port()) :: true
Удаляет связь между вызывающим процессом и заданным элементом (процессом или портом).
Если такой связи нет, эта функция ничего не делает. Если pid_or_port не существует, эта функция не генерирует ошибок и просто ничего не делает.
Значение возврата этой функции всегда true.
См. :erlang.unlink/1 для получения дополнительной информации.
Встраивается компилятором.
unregister(name)Source
@spec 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)Source
@spec 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.14.1/Process.html