让我们想象一下,我在elixir中产生了多个子进程。
defmodule Child do
def start(name) do
receive do
msg -> IO.puts "Message received by #{name}: #{inspect msg}"
end
end
end
defmodule Parent do
def main do
child1 = spawn_link (fn -> Child.start("1") end)
child2 = spawn_link (fn -> Child.start("2") end)
child3 = spawn_link (fn -> Child.start("3") end)
end
end
无论如何,我是否可以向当前进程(或其他进程)的所有所有发送消息?
send_to_children self(), "hello to all children"
在某种程度上,我可以告诉运行时将消息广播到链接到当前进程的所有进程?我当然可以将所有生成的pid存储在某种类型的数据结构中并在其上循环来执行此操作,但是如果有某种规范的方法来执行此操作,则看起来它会更高效且更不容易出错。
答案 0 :(得分:8)
由于您使用的是spawn_link
,因此您可以获取所有已关联流程的列表并向其发送消息:
defmodule Child do
def start(name) do
receive do
msg -> IO.puts "Message received by #{name}: #{inspect msg}"
end
end
end
defmodule Parent do
def main do
child1 = spawn_link (fn -> Child.start("1") end)
child2 = spawn_link (fn -> Child.start("2") end)
child3 = spawn_link (fn -> Child.start("3") end)
{:links, links} = Process.info(self, :links)
for pid <- links do
send pid, :foo
end
end
end
Parent.main
:timer.sleep(1000)
输出:
Message received by 2: :foo
Message received by 1: :foo
Message received by 3: :foo
我认为不可能直接获得流程的子流程列表:http://erlang.org/pipermail/erlang-questions/2013-April/073125.html。如果你从主管那里产生它们,有些方法,但不适用于任意情况。
答案 1 :(得分:1)
{:ok, _} = Registry.start_link(:duplicate, Registry.PubSubTest)
# process 1
{:ok, _} = Registry.register(Registry.PubSubTest, "room_1", [])
# process 2
{:ok, _} = Registry.regiser(Registry.PubSubTest, "room_1", [])
Registry.dispatch(Registry.PubSubTest, "room_1", fn entries ->
for {pid, _} <- entries, do: send(pid, {:broadcast, "world"})
end)
#=> :ok