Процесс
Удобства для работы с процессами и словарем процессов.
Помимо функций, доступных в этом модуле, модуль 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 , не найден. Это может произойти, если таймер истек, был отменён или 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)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, возвращаемого этой функцией.
См. :erlang.processes/0 для получения дополнительной информации.
Встраивается компилятором.
Примеры
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.
См. "Нужда в мониторинге" для примера. См. :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, или 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— абсолютное значение времени эрланга в момент монотонного времени, когда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.13.4/Process.html