[erlang-questions] Executing concurrently

Richard O'Keefe <>
Wed Mar 4 00:44:13 CET 2009


On 4 Mar 2009, at 5:41 am, Joe Armstrong wrote:
[an implementation of the two-calls-to-one-function-lets-one-
  proceed-and-fails-the-other request.]

Thanks to the existence of
  - the self() function and
  - the process dictionary
it is possible for the behaviour of a function to depend on
which process it is invoked within.

Joe's solution has the function invoked in a new process.
If that satisfies the original poster's need, then I wonder
what that need might be.

Another approach makes use of locks -- as Joe suggested in his
message -- and goes roughly like

	f(...) ->
	   magic:acquire()
	   Result = guts_of_f(...),
	   magic:release(),
	   Result.

where ignoring the stuff about starting and registering
the magic process,

	acquire() ->
	    magic!{acquire, self()},
	    receive {magic,Outcome} -> ok = Outcome end.

	release() ->
	    magic!{release, self()}.

	magic_available() ->
	    receive
		{acquire,Pid)) -> Pid!{magic,ok}, magic_held(Pid)
	      ; {release,_}    -> exit()
	    end.

	magic_held(Owner) ->
	    receive
		{release,Owner} -> magic_available()
	      ; {release,_}     -> exit()
	      ; {acquire,Pid}   -> Pid!{magic,fail}
	    end.

WARNING: this is not only untested code, it is incomplete.
Also, instead of the magic process exiting, we really want
the client process to get an exception, but I'm too lazy
to bother.  And of course you probably want to catch
exceptions around the call to guts_of_f(...) so that the
magic token is always released.

In fact, what we have here is nothing other than a mutex
using trylock() and unlock() instead of the usual
lock() and unlock(), which makes me wonder why the process
that doesn't get to run the function should be failed
rather than just being told to try again later.

Joe said "this does not seem like good design",
and if he says it, you'd better believe it.





More information about the erlang-questions mailing list