首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

监督 | Supervisor

用于实施主管的行为模块。

主管是一个监督其他进程的进程,我们称之为子进程。主管人员用于建立称为监督树的分层过程结构。监督树提供容错功能,并封装我们的应用程序如何启动和关闭。

使用此模块实施的主管具有标准的接口功能集,并包含跟踪和错误报告功能。

实例

为了定义一个主管,我们需要首先定义一个将被监督的子进程。作为一个例子,我们将定义一个代表堆栈的GenServer:

代码语言:javascript
复制
defmodule Stack do
  use GenServer

  def start_link(state) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  ## Callbacks

  def init(stack) do
    {:ok, stack}
  end

  def handle_call(:pop, _from, [h | t]) do
    {:reply, h, t}
  end

  def handle_cast({:push, h}, t) do
    {:noreply, [h | t]}
  end
end

该堆栈是列表中的一个小包装。它允许我们将一个元素放在堆栈的顶部,通过预先添加到列表中,并通过模式匹配来获取堆栈的顶部。

我们现在可以启动一个主管,负责启动并监督我们的堆栈过程,如下所示:

代码语言:javascript
复制
# Start the supervisor with the stack as a single child.
#
# The first element of the tuple is the module containing
# the child implementation, the second is the argument
# given to start_link, in this case a stack with `:hello`.
{:ok, pid} = Supervisor.start_link([
  {Stack, [:hello]}
], strategy: :one_for_one)

# After started, we can query the supervisor for information
Supervisor.count_children(pid)
#=> %{active: 1, specs: 1, supervisors: 0, workers: 1}

请注意,在启动GenServer时,我们使用名称注册Stack,这使我们可以直接调用它并获取堆栈中的内容:

代码语言:javascript
复制
GenServer.call(Stack, :pop)
#=> :hello

GenServer.cast(Stack, {:push, :world})
#=> :ok

GenServer.call(Stack, :pop)
#=> :world

但是,我们的堆栈服务器存在一个错误。如果我们调用:pop并且堆栈是空的,它将会因为没有子句匹配而崩溃:

代码语言:javascript
复制
GenServer.call(Stack, :pop)
** (exit) exited in: GenServer.call(Stack, :pop, 5000)

幸运的是,由于服务器正在由一位主管进行监督,因此主管会自动启动一个新的服务器,最初的堆栈为[:hello]

代码语言:javascript
复制
GenServer.call(MyStack, :pop)
#=> :hello

主管支持不同的策略; 在上面的例子中,我们选择了:one_for_one。此外,每个主管可以有许多员工和主管作为子女,每个主管都有其特定的配置,关机值和重启策略。

本文档的其余部分将介绍如何启动子进程,如何指定子进程,以及不同的监管策略等。

初始化过程

在上一节中,我们已经创建了一个有一个子类的监督员:

代码语言:javascript
复制
Supervisor.start_link([
  {Stack, [:hello]}
], strategy: :one_for_one)

给出的第一个参数start_link是一个孩子列表。在上面的例子中,我们已经通过一个元组,其中所述子是由实现Stack模块和接收的初始参数[:hello]Stack.start_link/1

一般来说,启动子进程分三个步骤进行:

  1. 首先是主管的电话Stack.child_spec([:hello])。该功能必须返回描述过程监督方式的子规范Stack。当你use GenServer,一个child_spec/1是自动为您定义,但我们将看到何时以及如何进行配置。当管理员启动时(或在热代码升级的情况下),该功能被调用一次。

2. 该子规范指出哪些功能调用,启动子进程的主管。默认情况下,它是start_link/1函数,接收相同的参数,并在与child_spec/1函数相同的模块中定义。每次需要新的子进程时都会调用此函数。例如,当我们Stack在前一次会话中崩溃时,Stack.start_link([:hello])再次调用它来启动一个新的堆栈。

3. 最后,Stack.start_link/1启动一个运行的新进程Stack.init/1,它负责设置一个对消息作出反应的进程。

总而言之,当它Supervisor.start_link(children, opts)被调用时,它遍历儿童列表并检索它们child_spec/1。然后每个孩子的规范描述了每个孩子是如何开始的,通常是通过start_link/1函数。主管调用start_link/1它初始化的时间以及子进程何时需要重启。作为第一步,开始的新进程start_link/1经常执行init回调。该init回调是我们初始化和配置子进程。

子规范

儿童规范描述了主管应该如何启动和监督儿童流程。我们了解到,当我们调用时 use GenServer,a Stack.child_spec/1会自动为我们定义。我们来调用它并查看它返回的内容:

Stack.child_spec([:hello]) #=> %{id:Stack,start: {Stack,:start_link, [[:hello]]}, restart::permanent, shutdown:5000, type::worker }

子规格包含5个键。前两个是必需的,其余的是可选的:

  1. :id - 用于由主管内部识别儿童规格的值; 默认为给定的模块。如有冲突:id,主管将拒绝初始化并要求明确的ID。该密钥是必需的。
  • :start-一个带有模块-函数-args的元组将被调用以启动子进程。这把钥匙是必需的。
  • :restart - 定义何时应该重新启动终止子进程的原子(请参见下面的“重新启动值”部分)。该键是可选的,默认为:permanent
  • :shutdown - 定义应如何终止子进程的原子(请参见下面的“关闭值”部分)。该密钥是可选的,默认5000如果类型是:worker:infinity如果类型是:supervisor
  • :type- 如果子进程是:worker:supervisor。该键是可选的,默认为:worker

有一个叫做第六个键,:modules很少改变,它是根据中的值自动设置的:start

大多数时候,您正在执行的行为模块将负责child_spec/1为您设置适当的行为。例如,use Supervisor将定义一个child_spec/1其中:type被设置为:supervisor:shutdown:infinity。不过,如果您需要自定义某种行为,可以通过定义自己的child_spec/1功能或通过传递选项来实现use。例如,要指定GenServer关闭限制为10秒(10_000毫秒)的人,可以这样做:

代码语言:javascript
复制
use GenServer, shutdown: 10_000

让我们了解一下:shutdown:restart

Shutdown values (:shutdown)

控件中支持下列关闭值:shutdown备选方案:

  • :brutal_kill- 子进程无条件终止使用Process.exit(child, :kill)
  • 任何整数> = 0 - 管理员在发出Process.exit(child, :shutdown)信号后等待孩子终止的时间量(以毫秒为单位)。如果子进程没有陷阱退出,则初始:shutdown信号将立即终止子进程。如果子进程陷入退出,它将以毫秒为终止时间。如果它没有在指定时间内终止,则子过程由监督员通过无条件终止Process.exit(child, :kill)
  • :infinity - 作为整数工作,除非主管将无限期地等待孩子终止。如果儿童进程是一名主管,建议的价值是:infinity让主管及其子女有足够的时间关闭。这个选项可以与普通员工一起使用,但是这样做是不鼓励的,需要非常小心。如果不谨慎使用并且子进程没有终止,则意味着您的应用程序永远不会终止。

重新启动值(:重新启动)

:restart选项控制主管应认为是否成功终止。如果终止成功,主管将不会重新启动孩子。如果子进程崩溃,主管将启动一个新进程。

:restart选项支持以下重新启动值:

  • :permanent-子类进程总是重新启动。
  • :temporary-无论监督战略如何,子类进程从未重新启动。
  • :transient- 子进程只有在异常终止时才会重新启动,也就是说,退出的原因不是:normal:shutdown{:shutdown, term}

有关退出原因及其影响的更完整理解,请参见下一节“退出原因”。

退出原因

主管根据其:restart配置重启子进程。例如,何时:restart设置:transient,监督员不会重新启动子进程,以防因为理由退出:normal:shutdown{:shutdown, term}

因此,人们可能会问:当我退出时,我应该选择哪个退出理由?有三种选择:

  • :normal-在这种情况下,退出将不会被记录,在瞬态模式下不会重新启动,并且链接的进程不会退出
  • :shutdown{:shutdown, term}-在这种情况下,退出不会被记录,在瞬态模式下不会重新启动,除非进程捕获出口,否则链接进程退出的原因相同
  • 任何其他术语 - 在这种情况下,退出将被记录,在瞬态模式下重新启动,并且链接进程以相同的原因退出,除非它们陷入退出

注意到达到最大重启强度的主管将:shutdown有理由退出 。在这种情况下,只有在其:restart选项被设置为:permanent (默认)的情况下定义其子规格时,管理程序才会重新启动。

基于模块的主管

在上面的例子中,通过将监督结构传递给监督员start_link/2。但是,监督人员也可以通过明确定义监督模块来创建:

defmoduleMyApp.Supervisor do# Automatically defines child_spec/1useSupervisordefstart_link(arg) doSupervisor.start_link(__MODULE__, arg, name:__MODULE__)enddefinit(_arg)doSupervisor.init([ {Stack, [:hello]} ], strategy::one_for_one) endend

这两种方法之间的区别在于,基于模块的主管可以更直接地控制主管如何初始化。Supervisor.start_link/2我们没有使用自动初始化的孩子列表进行调用,而是在init/1回调的旁边定义了一位主管,并通过调用手动初始化了孩子,并Supervisor.init/2传递了我们将要提供的相同参数start_link/2

在下列情况下您可能需要使用基于模块的主管:

  • 您需要对主管初始化执行一些特定的操作,比如设置ETS表。
  • 您希望执行部分热代码交换树。例如,如果添加或删除子级,则基于模块的监督将直接添加和删除新的子级,而动态监视则要求重新启动整棵树以执行此类交换。

注意

use Supervisor定义了一个child_spec/1函数,允许将定义的模块置于监督树下。生成的child_spec/1可以使用以下选项进行自定义:

  • :id-子规范id,不符合当前模块
  • :start- 如何启动子进程(默认为调用__MODULE__.start_link/1
  • :restart-当主管重新启动时,默认为:permanent

start_link/2, init/2 and strategies

到目前为止,我们已经启动了主管将一个孩子作为元组传递给一个调用:one_for_one

代码语言:javascript
复制
Supervisor.start_link([
  {Stack, [:hello]}
], strategy: :one_for_one)

或:

代码语言:javascript
复制
Supervisor.init([
  {Stack, [:hello]}
], strategy: :one_for_one)

但是,可以用三种不同的格式指定子级,并且主管支持不同的选项。让我们正式定义一下。

给出的第一个参数start_link/2是可能是以下任一种的子列表:

  • 一个模块 - 比如Stack。在这种情况下,它相当于传递{Stack, []}(这意味着Stack.child_spec/1调用一个空的关键字列表)
  • 一个元组,其中一个模块作为第一个元素,开始参数作为第二个{Stack, [:hello]}当使用这种格式时,主管将从给定模块中检索子规范。
  • 表示子规范本身的映射--例如上一节中概述的子规范映射。

第二个参数是选项的关键字列表:

  • :strategy - 重新启动策略选项。它可以是:one_for_one:rest_for_one:one_for_all,或:simple_one_for_one。请参阅“策略”部分。
  • :max_restarts - 一段时间内允许的最大重启次数。默认为3
  • :max_seconds- :max_restarts适用的时间范围。默认为5

:strategy选项是必需的,默认情况下最多可以在5秒内重新启动3次。

策略

管理器支持不同的监督策略(通过:strategy选项,如上所示):

  • :one_for_one-如果子进程终止,则只重新启动该进程。
  • :one_for_all - 如果子进程终止,则所有其他子进程终止,然后重新启动所有子进程(包括终止的进程)。
  • :rest_for_one-如果一个子进程终止,子进程的“REST”,即在终止后的子进程按开始顺序结束后的“REST”进程被终止。然后重新启动终止的子进程和其余的子进程。
  • :simple_one_for_one-类似于:one_for_one但更适合于动态附加孩子。此策略要求主管规范只包含一个子级。当使用此策略时,本模块中的许多函数的行为略有不同。

简单的one for one

:simple_one_for_one当您想要动态启动和停止受监督的孩子时,主管是很有用的。作为一个例子,让我们动态地启动多个代理来保持状态。

:simple_one_for_one主管人员的一个重要方面是,我们经常想在:start以后动态地启动孩子时传递参数,而不是在定义孩子规范时。在这种情况下,我们不应该这样做

Supervisor.start_link [ {Agent,fn -> 0end} ]

因为上面的例子会强制所有代理具有相同的状态。在这种情况下,我们可以使用该child_spec/2函数来构建和覆盖子规范中的字段:

# Override the :start field to have no args.

# The second argument has no effect thanks to it. agent_spec = Supervisor.child_spec(Agent,start: {Agent,:start_link, []})

# We start a supervisor with a simple one for one strategy.

# The agent won't be started now but later on. {:ok, sup_pid} = Supervisor.start_link([agent_spec], strategy::simple_one_for_one)

# No child worker is active until start_child is calledSupervisor.count_children(sup_pid)

#=> %{active: 0, specs: 1, supervisors: 0, workers: 0}

一个策略中的简单策略只能定义一个孩子,当我们调用时,它可以作为模板start_child/2

主管启动后,让我们动态地启动代理:

{:ok, agent1} = Supervisor.start_child(sup_pid, [fn -> 0end]) Agent.update(agent1, & &1 + 1) Agent.get(agent1, & &1) #=> 1 {:ok, agent2} = Supervisor.start_child(sup_pid, [fn -> %{} end]) Agent.get(agent2, & &1) #=> %{}Supervisor.count_children(sup_pid) #=> %{active: 2, specs: 1, supervisors: 0, workers: 2}

名称注册

监督人员必须与GenServer。相同的名称注册规则。在文档中阅读有关这些规则的更多信息GenServer

总结

类型

child()

child_spec()

主管规范

flag()

给予start_link/2和的选项init/2

name()

主管的名称

on_start()

start_link函数的返回值

on_start_child()

start_child函数的返回值

option()

start*功能使用的选项值

options()

start*功能使用的选项

strategy()

支持的策略

supervisor()

supervisor参考

函数

child_spec(module_or_map, overrides)

构建并覆盖子规范

count_children(supervisor)

返回包含给定超级用户计数值的地图

delete_child(supervisor, child_id)

删除由标识的子规范child_id

init(children, options)

接收要初始化的儿童列表和一组选项

restart_child(supervisor, child_id)

重新启动由标识的子进程child_id

start_child(supervisor, child_spec_or_args)

动态地添加一个子规范supervisor并启动该子项

start_link(children, options)

与给定的子类开始一位主管

start_link(module, arg, options \\ [])

用给定的module和开始一个主管进程arg

stop(supervisor, reason \\ :normal, timeout \\ :infinity)

同时停止给定的主管reason

terminate_child(supervisor, pid_or_child_id)

终止给定的子类,由PID或孩子ID标识

which_children(supervisor)

返回包含给定主管的所有子项的信息的列表

回调

init(args)

调用回调以启动管理程序并在热代码升级期间进行回调

Link to this section

类型

Link to this type

child()View Source

代码语言:javascript
复制
child() :: pid | :undefined

Link to this type

child_spec()View Source

代码语言:javascript
复制
child_spec() :: :supervisor.child_spec

Supervisor规范

Link to this type

flag()View Source

代码语言:javascript
复制
flag ::
  {:strategy, strategy} |
  {:max_restarts, non_neg_integer} |
  {:max_seconds, pos_integer}

给予start_link/2和的选项init/2

name()View Source

代码语言:javascript
复制
name() :: atom | {:global, term} | {:via, module, term}

Supervisor名称

Link to this type

on_start()View Source

代码语言:javascript
复制
on_start ::
  {:ok, pid} |
  :ignore |
  {:error, {:already_started, pid} | {:shutdown, term} | term}

start_link函数的返回值

Link to this type

on_start_child()View Source

代码语言:javascript
复制
on_start_child ::
  {:ok, child} |
  {:ok, child, info :: term} |
  {:error, {:already_started, child} | :already_present | term}

start_child函数的返回值

option()View Source

代码语言:javascript
复制
option() :: {:name, name} | flag

start*函数使用的选项值

Link to this type

options()View Source

代码语言:javascript
复制
options() :: [option, ...]

start*函数使用的选项

Link to this type

strategy()View Source

代码语言:javascript
复制
strategy ::
  :simple_one_for_one |
  :one_for_one |
  :one_for_all |
  :rest_for_one

支持的策略

Link to this type

supervisor()View Source

代码语言:javascript
复制
supervisor() :: pid | name | {atom, node}

Supervisor安靠

函数

Link to this function

child_spec(module_or_map, overrides)View Source

代码语言:javascript
复制
child_spec(child_spec | {module, arg :: term} | module, keyword) :: child_spec

构建并覆盖子规范。

类似start_link/2并且init/2,它需要一个 module{module, arg}或地图作为子规范。如果给出模块,则通过调用来检索规范 module.child_spec(arg)

在检索子规范之后,这些字段config 将直接应用于子规范。如果config有不映射到任何子规范字段的键,则会引发错误。

请参阅模块文档中的“子规范”部分,了解覆盖的所有可用键。

例子

:id当监视树中需要多次启动相同的模块时,此功能通常用于设置选项:

代码语言:javascript
复制
Supervisor.child_spec({Agent, fn -> :ok end}, id: {Agent, 1})
#=> %{id: {Agent, 1},
      start: {Agent, :start_link, [fn -> :ok end]}}

当在:simple_one_for_one策略下启动模块时需要更改参数的数量时也可以使用它,因为大多数参数可以动态给定:

代码语言:javascript
复制
Supervisor.child_spec(Agent, start: {Agent, :start_link, []})
#=> %{id: Agent,
      start: {Agent, :start_link, []}}

Link to this function

count_children(supervisor)View Source

代码语言:javascript
复制
count_children(supervisor) :: %{specs: non_neg_integer, active: non_neg_integer, supervisors: non_neg_integer, workers: non_neg_integer}

返回包含给定超级用户计数值的地图。

该地图包含以下键:

  • :specs - 注销或存活的子进程总数
  • :active-此主管管理的所有正在运行的子进程的计数
  • :supervisors - 所有主管人员的人数,无论这些子监督员是否还活着
  • :workers - 所有工作进程的数量,不管这些子进程是否仍然存在

delete_child(supervisor, child_id)View Source

代码语言:javascript
复制
delete_child(supervisor, term) ::
  :ok |
  {:error, error} when error: :not_found | :simple_one_for_one | :running | :restarting

删除由标识的子规范child_id

相应的子进程不能运行;terminate_child/2 如果它正在运行,用它来终止它。

如果成功,此函数返回:ok。如果child_id未找到该函数,或者当前进程正在运行或正在重新启动,则此函数可能会返回错误并显示相应的错误元组。

:simple_one_for_one主管不支持此操作。

init(children, options)View Source

代码语言:javascript
复制
init([child_spec | {module, term} | module], flag) :: {:ok, tuple}

接收要初始化的子列表和一组选项。

这通常在init/1基于模块的管理者回调结束时调用。有关详细信息,请参阅模块文档中的“基于模块的管理程序”和“start_link / 2,init / 2和策略”部分。

这个函数返回一个包含主管标志和子规范的元组。

示例

代码语言:javascript
复制
def init(_arg) do
  Supervisor.init([
    {Stack, [:hello]}
  ], strategy: :one_for_one)
end

选项

  • :strategy - 重新启动策略选项。它可以是:one_for_one:rest_for_one:one_for_all,或:simple_one_for_one。您可以在Supervisor模块文档中了解有关策略的更多信息。
  • :max_restarts-在一个时间框架内允许的最大重新启动量。默认为3...
  • :max_seconds-时限:max_restarts适用。默认为5...

:strategy选项是必需的,默认情况下最多可以在5秒内重新启动3次。检查Supervisor模块以获取可用策略的详细描述。

restart_child(supervisor, child_id)

代码语言:javascript
复制
restart_child(supervisor, term) ::
  {:ok, child} |
  {:ok, child, term} |
  {:error, error} when error: :not_found | :simple_one_for_one | :running | :restarting | term

重新启动由child_id标识的子进程。

子规范必须存在,并且相应的子进程不能运行。

注意,对于临时子程序,子规范在子程序终止时会自动删除,因此无法重新启动这些子规范。

如果子进程启动函数返回{:ok, child}{:ok, child, info},将PID添加到监控器,此函数返回相同的值。

如果子进程启动函数返回:ignore,则PID将保持设置为:undefined并且此函数返回{:ok, :undefined}

如果child_id未找到,或者当前进程正在运行或正在重新启动。

如果子进程启动函数返回错误元组或错误值,或者如果失败,则返回{:error, error}

:simple_one_for_one主管不支持此操作。

start_child(supervisor,child_spec_or_args)

代码语言:javascript
复制
start_child(supervisor, :supervisor.child_spec | [term]) :: on_start_child

动态地将子规范添加到supervisor然后开始那个子进程。

child_spec应该是有效的子女规范(除非主管是:simple_one_for_one主管,见下文)。子进程将按照子规范中的定义启动。

:simple_one_for_one使用监督员中定义的子规范而不是a的情况下child_spec,预期可以使用任意的术语列表。子进程将通过将给定列表附加到子规范中的现有函数参数来启动。

如果具有指定标识的子规范已经存在,将child_spec被丢弃,并且此函数分别返回一个错误,:already_started或者:already_present如果相应的子进程正在运行或者没有运行。

如果子进程启动函数返回,{:ok, child}或者{:ok, child, info},然后将子进程指定和PID添加到主管,并且此函数返回相同的值。

如果子进程启动函数返回:ignore,则将子进程规范添加到主管,PID设置为:undefined并且此函数返回{:ok, :undefined}

如果子进程启动函数返回错误元组或错误值,或者失败,则会丢弃子规范,并且此函数返回{:error, error}其中error包含有关错误和子规范信息的术语。

start_link(children, options)

代码语言:javascript
复制
start_link(module, term) :: on_start
代码语言:javascript
复制
start_link([:supervisor.child_spec | {module, term} | module], options) :: on_start

开始一个主管与给定的子进程。

子是一个模块列表,包含模块和参数的2元组元素或带有子规范的映射。需要通过:strategy选项提供策略。有关示例和其他选项,请参阅“start_link/2,init/2和策略”。

这些选项也可用于注册管理员名称。支持的值在GenServer模块文档的“名称注册”部分中有描述。

如果主管及其子进程成功催生了(如果每个子进程的启动函数返回{:ok, child}{:ok, child, info}:ignore)这个函数返回{:ok, pid},这里pid是主管的PID。如果管理员被赋予一个名称并且具有指定名称的进程已经存在,则该函数返回{:error, {:already_started, pid}}pid该进程的PID 在哪里。

如果任何子进程的启动函数失败或返回错误元组或错误值,监督员将首先终止:shutdown所有已启动的子进程,然后自行终止并返回{:error, {:shutdown, reason}}

请注意,启动此功能的主管与父进程关联,不仅会在崩溃时退出,而且如果父进程:normal有理由退出。

start_link(module, arg, options \ [])

代码语言:javascript
复制
start_link(module, term, GenServer.options) :: on_start

用给定的modulearg开始一个主管进程。

要启动主管,init/1回调将在给定的调用module,以arg作为其参数。init/1回调必须返回可以在init/2功能的帮助下创建的管理员规范。

如果init/1回调返回:ignore,则此函数:ignore也会返回,并且管理程序将以原因终止:normal。如果失败或返回的值不正确,则此函数返回{:error, term}其中term包含有关错误的信息的术语,并且管理程序将以原因终止term

:name也可以给出该选项以注册主管人员姓名,支持的值在GenServer模块文档的“姓名注册”部分进行描述。

stop(supervisor, reason \ :normal, timeout \ :infinity)

代码语言:javascript
复制
stop(supervisor, reason :: term, timeout) :: :ok

同时停止给定的主管reason

如果主管以给定的原因终止,它将返回:ok。如果以其他原因终止,则呼叫退出。

该函数保持关于错误报告的OTP语义。如果原因不是:normal:shutdown或者{:shutdown, _}记录了错误报告。

terminate_child(supervisor, pid_or_child_id)

代码语言:javascript
复制
terminate_child(supervisor, pid | term) ::
  :ok |
  {:error, error} when error: :not_found | :simple_one_for_one

终止给定的子进程,由PID或子进程ID标识。

如果主管不是一个:simple_one_for_one,则预计该子进程ID,并且该过程(如果有的话)终止; 子进程的说明一直保留,除非孩子是临时的。

:simple_one_for_one主管的情况下,预计PID。如果给出子规范标识符而不是a pid,则该函数返回{:error, :simple_one_for_one}

主管可以稍后重新启动非临时子流程。子进程也可以通过调用显式重启restart_child/2。使用delete_child/2删除的子规范。

如果成功,此函数返回:ok。如果给定子ID没有子规范,或者没有给定PID的进程,则此函数返回{:error, :not_found}

which_children(supervisor)

代码语言:javascript
复制
which_children(supervisor) :: [{term | :undefined, child | :restarting, :worker | :supervisor, :supervisor.modules}]

返回包含给定主管的所有子级信息的列表。

注意,在监视大量在低内存条件下的子函数时调用此函数可能导致内存不足异常。

此函数返回{id, child, type, modules}元组,其中:

  • id - 在子规范中定义或:在simple_one_for_one主管的情况下未定义
  • child - 相应子进程的PID,:如果进程将要重新启动,则重新启动,或者:如果没有此进程,则为undefined
  • type---:worker:supervisor,由子规范指定。
  • modules-子进程规格所规定的

init(args)

代码语言:javascript
复制
init(args :: term) ::
  {:ok, {:supervisor.sup_flags, [:supervisor.child_spec]}} |
  :ignore

调用回调以启动管理程序并在热代码升级期间进行回调。

扫码关注腾讯云开发者

领取腾讯云代金券