Spec-Zone.ru › Elixir 1.14

Процесс

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

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

Функции

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:

  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 передаётся немедленно.

См. "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

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

  • 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 — абсолютное значение монотонного времени 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

Spec-Zone.ru

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