Arun Dhyani
Arun Dhyani

Reputation: 131

Non anonymous function inside spawn is not executing asynchronously

So here is my code :

 defmodule Test do

   def fun() do
     Process.sleep(10000)
     IO.puts "sleep over"
   end

   def dummy(:b) do
     spawn(fun())
   end
   def dummy(:a) do
     spawn(Test,:fun,[])
   end

   def dummy() do
     spawn(fn -> Process.sleep(10000)
                 IO.puts "sleep over"
     end)
     IO.puts "process started"
   end
 end

On running this code and executing various dummy functions I got this output:

iex(1)> c("test.exs")
[Test]
iex(2)> Test.dummy
process started
:ok
sleep over
iex(3)> Test.dummy :
** (SyntaxError) iex:3: unexpected token: ":" (column 12, codepoint U+003A)

iex(3)> Test.dummy :a
#PID<0.111.0>
iex(4)> 
nil
iex(5)> 
nil
sleep over           
iex(6)> Test.dummy :b
sleep over
** (ArgumentError) argument error
    :erlang.spawn(:ok)
iex(6)> 

My main concern is why when we use spawn/1 with not an anonymous function it does not asynchronously execute the function but wait for this function to execute while in both other the functions inside spawn are executed asynchronously (as I expected) .

Upvotes: 1

Views: 216

Answers (1)

Badu
Badu

Reputation: 1082

Use spawn(&fun/0).

What you are doing now is evaluating fun and passing the result to spawn. That’s why it waits for fun to finish then sends :ok (which is the response from IO.puts("sleep over") - last statement in fun) to spawn. That’s what the error :erlang.spawn(:ok) is about.

You have to capture the function and pass it as argument to spawn Read on Function Capturing

Upvotes: 6

Related Questions