Spec-Zone.ru › Elixir 1.13

Процесс

Удобства для работы с процессами и словарем процессов.

Помимо функций, доступных в этом модуле, модуль 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()

Место назначения процесса.

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)

Отправляет сообщение заданному 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()]
END_OF_DOCUMENT_MARKER

Функции

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:

  1. Если процесс pid не ловит сигналы выхода, он завершится с заданным reason.

  2. Если процесс 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.

Встроенная компилятором.

END_OF_DOCUMENT_MARKER

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.

Зарезервированы следующие имена и не могут быть присвоены процессам или портам:

  • nil
  • false
  • true
  • :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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API