Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of `receive after 0` (also known as Selective Receives)

Tags:

erlang

From the Learn You Some Erlang for Great Good!

Another special case is when the timeout is at 0:

flush() -> 
  receive
   _ -> flush() 
  after 0 -> 
    ok 
  end
.

When that happens, the Erlang VM will try and find a message that fits one of the available patterns. In the case above, anything matches. As long as there are messages, the flush/0 function will recursively call itself until the mailbox is empty. Once this is done, the after 0 -> ok part of the code is executed and the function returns.

I don't understand purpose of after 0. After reading above text I thought it was like after infinity (waiting forever) but I changed a little the flush function:

flush2() ->
  receive
    _ -> timer:sleep(1000), io:format("aa~n"), flush()
  after 0 ->
    okss
  end
.

flush3() ->
  receive
    _ -> io:format("aa~n"), flush()
  after 0 ->
    okss
  end
.

In the first function it waits 1 second and in the second function it doesn't wait.
In both cases it doesn't display a text (aa~n).
So it doesn't work as after infinity.

If block between the receive and the after are not executed then above 2 codes can be simplified to:

flush4() ->
  okss
.

What I am missing?

ps. I am on the Erlang R16B03-1, and author of the book was, as fair I remember, was on the Erlang R13.

like image 538
Darek Nędza Avatar asked Nov 30 '22 11:11

Darek Nędza


1 Answers

Every process has a 'mailbox' -- message queue. Messages can be fetched by receive. if there is no messages in the queue. after part specifies how much time 'receive will wait for them. So after 0 -- means process checking (by receive ) if any messages in the queue and if queue is empty immediately continue to next instructions.

It can be used for instance if we want periodically check if any messages here and to do something (hopefully helpful) if there is no messages.

like image 161
Odobenus Rosmarus Avatar answered Dec 05 '22 02:12

Odobenus Rosmarus