"id" 和 "name" 在 Elixir Supervisor/Process 中是否相同?
Are "id" and "name" the same in Elixir Supervisor/Process?
我创建了一个名为 ElectionManager.Application
的主管和一个工人。
然后查看了那些进程的信息:
iex(3)> proc = Process.whereis(ElectionManager.Application)
#PID<0.158.0>
iex(4)> Process.info proc
[registered_name: ElectionManager.Application,
current_function: {:gen_server, :loop, 7},
initial_call: {:proc_lib, :init_p, 5}, status: :waiting, message_queue_len: 0,
messages: [], links: [#PID<0.156.0>, #PID<0.159.0>],
dictionary: ["$initial_call": {:supervisor, Registry.Supervisor, 1},
"$ancestors": [#PID<0.156.0>]], trap_exit: true,
error_handler: :error_handler, priority: :normal, group_leader: #PID<0.155.0>,
total_heap_size: 986, heap_size: 610, stack_size: 10, reductions: 339,
garbage_collection: [max_heap_size: %{error_logger: true, kill: true, size: 0},
min_bin_vheap_size: 46422, min_heap_size: 233, fullsweep_after: 65535,
minor_gcs: 2], suspending: []]
iex(7)> {id, child, type, modules} = Supervisor.which_children(proc) |> List.first
{ElectionManager.Application.PIDPartition0, #PID<0.159.0>, :worker,
[Registry.Partition]}
iex(8)> Process.info child
[registered_name: ElectionManager.Application.PIDPartition0,
current_function: {:gen_server, :loop, 7},
initial_call: {:proc_lib, :init_p, 5}, status: :waiting, message_queue_len: 0,
messages: [], links: [#PID<0.158.0>, #PID<0.156.0>],
dictionary: ["$initial_call": {Registry.Partition, :init, 1},
"$ancestors": [ElectionManager.Application, #PID<0.156.0>]], trap_exit: true,
error_handler: :error_handler, priority: :normal, group_leader: #PID<0.155.0>,
total_heap_size: 233, heap_size: 233, stack_size: 10, reductions: 47,
garbage_collection: [max_heap_size: %{error_logger: true, kill: true, size: 0},
min_bin_vheap_size: 46422, min_heap_size: 233, fullsweep_after: 65535,
minor_gcs: 0], suspending: []]
在 Elixir 文档中,name
和 child_id
之间的区别不明确,似乎有一个 id: something
工人选项和 name: something
进程选项和监事。我很困惑。
从上面看,id
和registered_name
好像是一样的。
我想让我的主管监督多个 children,但默认情况下我不能这样做(我收到 :already_started
错误)。我应该同时更改名称和 ID,还是只更改其中一个?
id只是一个内部标识符,仅供工人的主管使用。对于同一主管中的所有工人,它必须是唯一的。
名称是您可以用来寻址进程的值,而不是使用其 PID。
您看到 name 和 id 的值相同的原因是主管默认使用进程名称作为 worker id。
姓名与主管无关。进程名称用于在您想要引用进程时查找进程,无论是监督的还是非监督的。
进程 ID 是 BEAM 用于进程的内部标识符,就像您的 OS 给每个进程一个 ID 一样。 Supervisor 捕获此 id 以便能够监控并在以后重新启动它。
你给supervisor的child id,用来保存children spec。如果您没有明确提供它,它就是用于启动 child 的模块的名称。它可以在以后用于检索 child 规范。
如果你想启动多个children使用同一个模块,你必须明确指定childid,因为两个children不能有相同的id(将 children 规范视为 child_id => child_spec).
的哈希映射
如果你需要启动多个children使用同一个模块,也许你正在寻找supervisor的simple_one_to_one
策略。使用它,您指定一次规格,并请求主管在 运行 时间启动 children(与其他 children 在启动时启动的情况不同)。
我创建了一个名为 ElectionManager.Application
的主管和一个工人。
然后查看了那些进程的信息:
iex(3)> proc = Process.whereis(ElectionManager.Application)
#PID<0.158.0>
iex(4)> Process.info proc
[registered_name: ElectionManager.Application,
current_function: {:gen_server, :loop, 7},
initial_call: {:proc_lib, :init_p, 5}, status: :waiting, message_queue_len: 0,
messages: [], links: [#PID<0.156.0>, #PID<0.159.0>],
dictionary: ["$initial_call": {:supervisor, Registry.Supervisor, 1},
"$ancestors": [#PID<0.156.0>]], trap_exit: true,
error_handler: :error_handler, priority: :normal, group_leader: #PID<0.155.0>,
total_heap_size: 986, heap_size: 610, stack_size: 10, reductions: 339,
garbage_collection: [max_heap_size: %{error_logger: true, kill: true, size: 0},
min_bin_vheap_size: 46422, min_heap_size: 233, fullsweep_after: 65535,
minor_gcs: 2], suspending: []]
iex(7)> {id, child, type, modules} = Supervisor.which_children(proc) |> List.first
{ElectionManager.Application.PIDPartition0, #PID<0.159.0>, :worker,
[Registry.Partition]}
iex(8)> Process.info child
[registered_name: ElectionManager.Application.PIDPartition0,
current_function: {:gen_server, :loop, 7},
initial_call: {:proc_lib, :init_p, 5}, status: :waiting, message_queue_len: 0,
messages: [], links: [#PID<0.158.0>, #PID<0.156.0>],
dictionary: ["$initial_call": {Registry.Partition, :init, 1},
"$ancestors": [ElectionManager.Application, #PID<0.156.0>]], trap_exit: true,
error_handler: :error_handler, priority: :normal, group_leader: #PID<0.155.0>,
total_heap_size: 233, heap_size: 233, stack_size: 10, reductions: 47,
garbage_collection: [max_heap_size: %{error_logger: true, kill: true, size: 0},
min_bin_vheap_size: 46422, min_heap_size: 233, fullsweep_after: 65535,
minor_gcs: 0], suspending: []]
在 Elixir 文档中,name
和 child_id
之间的区别不明确,似乎有一个 id: something
工人选项和 name: something
进程选项和监事。我很困惑。
从上面看,id
和registered_name
好像是一样的。
我想让我的主管监督多个 children,但默认情况下我不能这样做(我收到 :already_started
错误)。我应该同时更改名称和 ID,还是只更改其中一个?
id只是一个内部标识符,仅供工人的主管使用。对于同一主管中的所有工人,它必须是唯一的。
名称是您可以用来寻址进程的值,而不是使用其 PID。
您看到 name 和 id 的值相同的原因是主管默认使用进程名称作为 worker id。
姓名与主管无关。进程名称用于在您想要引用进程时查找进程,无论是监督的还是非监督的。
进程 ID 是 BEAM 用于进程的内部标识符,就像您的 OS 给每个进程一个 ID 一样。 Supervisor 捕获此 id 以便能够监控并在以后重新启动它。
你给supervisor的child id,用来保存children spec。如果您没有明确提供它,它就是用于启动 child 的模块的名称。它可以在以后用于检索 child 规范。
如果你想启动多个children使用同一个模块,你必须明确指定childid,因为两个children不能有相同的id(将 children 规范视为 child_id => child_spec).
的哈希映射如果你需要启动多个children使用同一个模块,也许你正在寻找supervisor的simple_one_to_one
策略。使用它,您指定一次规格,并请求主管在 运行 时间启动 children(与其他 children 在启动时启动的情况不同)。