Can I send a message to all child processes in elixir / erlang?

Suppose I create several child processes in an 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 

In any case, can I send a message to all the children of my current process (or some other process)?

 send_to_children self(), "hello to all children" 

As in some cases, can I say that the runtime broadcasts a message to all processes associated with the current process? I could, of course, store all the generated pids in some kind of data structure and iterate over them, but if there is some canonical way to do this, it looks like it will be more efficient and less error prone.

+5
source share
2 answers

Since you are using spawn_link , you can get a list of all related processes and send them a message:

 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 do not think that you can directly get a list of child processes of a process: http://erlang.org/pipermail/erlang-questions/2013-April/073125.html . There are ways if you create them from the dispatcher, but not for arbitrary cases.

+8
source

Have you watched PubSub? The only limitation is that all your processes will be called 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 
0
source

Source: https://habr.com/ru/post/1274916/


All Articles