small medium large xlarge

Dave_gnome_head_isolated_pragsmall
15 Jul 2013, 03:42
Dave Thomas (366 posts)
  • Repeat the two, changing spawn_link to spawn_monitor.
Generic-user-small
06 Jan 2015, 20:43
Pierre Sugar (57 posts)

The exit version

defmodule Crash4 do

  def one_time(sender) do
    send sender, {self, "Just a message from Crash4"}
    exit "Did it by purpose"
  end

  def check_for_message do
    receive do
      msg ->
        IO.puts "Received another message #{inspect msg}"
        check_for_message
    after 500 ->
      IO.puts "no more messages"
    end
  end

  def run do
    res = spawn_monitor(Crash4, :one_time, [self])

    IO.puts inspect res

    :timer.sleep(500)

    check_for_message
  end
end

Output:

iex(38)> Crash4.run
{#PID<0.792.0>, #Reference<0.0.0.8231>}
Received another message {#PID<0.792.0>, "Just a message from Crash4"}
Received another message {:DOWN, #Reference<0.0.0.8231>, :process, #PID<0.792.0>
, "Did it by purpose"}
no more messages
:ok
iex(39)>

The raise version

defmodule Crash3 do

  def one_time(sender) do
    send sender, {self, "Just a message from Crash3"}
    raise RuntimeError, message: "Did it by purpose"
  end

  def check_for_message do
    receive do
      {sender, msg} ->
        IO.puts "Received message #{inspect msg} from #{inspect sender}"
        check_for_message
       msg ->
        IO.puts "Received another message #{inspect msg}"
        check_for_message
    after 500 ->
      IO.puts "no more messages"
    end
  end

  def run do
    res = spawn_monitor(Crash2, :one_time, [self])

    IO.puts inspect res

    :timer.sleep(500)

    check_for_message
  end
end

Output:

iex(29)> Crash3.run
{#PID<0.761.0>, #Reference<0.0.0.7969>}

21:27:26.495 [error] Error in process <0.761.0> with exit value: {#{'__exception
__'=>true,'__struct__'=>'Elixir.RuntimeError',message=><<17 bytes>>},[{'Elixir.C
rash3',one_time,1,[{file,"crash3.exs"},{line,5}]}]}

Received another message "Just a message from Crash2"
Received another message {:DOWN, #Reference<0.0.0.7969>, :process, #PID<0.761.0>
, {%RuntimeError{message: "Did it by purpose"}, [{Crash3, :one_time, 1, [file: '
crash3.exs', line: 5]}]}}
no more messages
:ok
iex(30)>
C2f77d9bcc71d1f9ddabd89a8ddf9615_pragsmall
10 Jul 2015, 03:35
Rebecca Skinner (6 posts)

The outputs for spawn_link and spawn_monitor look identical to me, except the EXIT message is replaced with a DOWN message?

Me_pragsmall
17 Feb 2017, 04:51
Mike Dalton (1 post)

Source

defmodule SpawnMonitor do
  import :timer, only: [ sleep: 1 ]

  def spawned_function(sender) do
    IO.puts "spawned_function receiving message"
    send sender, { :ok, "Hello" }
    IO.puts "spawned_function sending message to parent"
    exit(:normal)
  end

  def spawner do
    IO.puts "sending spawned_function a message"
    spawn_monitor(SpawnMonitor, :spawned_function, [self()])
    sleep(500)
    receiver()
  end

  def receiver do
    receive do
      { :ok, message } ->
        IO.puts "receiving message in parent #{message}"
        receiver()
    after 100 -> IO.puts "no more messages"
    end
  end
end

SpawnMonitor.spawner

Output

$ elixir spawn_monitor.exs 
sending spawned_function a message
spawned_function receiving message
spawned_function sending message to parent
receiving message in parent Hello
no more messages

Source (with exception after child sends message)

defmodule SpawnMonitor do
  import :timer, only: [ sleep: 1 ]

  def spawned_function(sender) do
    IO.puts "spawned_function receiving message"
    send sender, { :ok, "Hello" }
    IO.puts "spawned_function sending message to parent"

    raise "AN EXCEPTION"

    exit(:normal)
  end

  def spawner do
    IO.puts "sending spawned_function a message"
    spawn_monitor(SpawnMonitor, :spawned_function, [self()])
    sleep(500)
    receiver()
  end

  def receiver do
    receive do
      { :ok, message } ->
        IO.puts "receiving message in parent #{message}"
        receiver()
    after 100 -> IO.puts "no more messages"
    end
  end
end

SpawnMonitor.spawner

Output

$ elixir spawn_monitor.exs 
sending spawned_function a message
spawned_function receiving message
spawned_function sending message to parent

23:50:46.352 [error] Process #PID<0.76.0> raised an exception
** (RuntimeError) AN EXCEPTION
    spawn_monitor.exs:9: SpawnMonitor.spawned_function/1
receiving message in parent Hello
no more messages
Generic-user-small
09 Apr 2018, 17:55
Renan Araujo Lage (1 post)

Rebecca Skinner:

The outputs for spawn_link and spawn_monitor look identical to me, except the EXIT message is replaced with a DOWN message?

That’s probably because you’re setting the :trap_exit flag to true in exercises 3 and 4. The exercises are meant to show you how linking and monitoring differ in propagating the termination from one process to another. Setting the flag defeats that purpose by having them behave equally as pointed out by theofanis melios

You must be logged in to comment