Let's imagine that I'm spawning multiple child processes in 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
Is there anyway that I can send a message to all of the children of my current process (or some other process)?
send_to_children self(), "hello to all children"
As in, some way that I can tell the runtime to broadcast a message to all of processes linked to a current process? I could of course store all of the spawned pids in a data structure of some kind and loop over it to do this, but if there is some kind of canonical way to do this it seems like it would be more efficient and less error prone.
Since you're using spawn_link
, you can fetch list of all linked processes and send a message to them:
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)
Output:
Message received by 2: :foo
Message received by 1: :foo
Message received by 3: :foo
I don't think it's possible to get a list of child processes of a process directly: http://erlang.org/pipermail/erlang-questions/2013-April/073125.html. There are ways if you spawn them from a Supervisor but not for arbitrary cases.
did you look at PubSub? The only restriction is that all your processes will be named the same https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub
{: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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With