Spec-Zone.ru › Elixir 1.10

Процесс

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

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

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()]
END_OF_DOCUMENT_MARKER

Функции

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:

  1. Если процесс pid не ловит сигналы завершения, процесс 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)

Спецификации

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/порт уже зарегистрирован под другим именем

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

  • 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

Отправляет сообщение заданному объекту.

Объект может быть удалённым или локальным 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

Spec-Zone.ru

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