Gen_server and multiple processes

Ulf Wiger <>
Fri Dec 20 17:17:31 CET 2002

On Fri, 20 Dec 2002, hfventer wrote:

>Just to check, you mean to actually spawn a new OTP
>gen_server?  Is this not slow since it has quite a bit of
>overhead. The idea we had was to have one gen_server that
>spawns its own worker threads in the handle_call.

I have submitted a contribution to called mdisp.

(when it actually appears depends a bit on how the
contributions moderator works through the Holidays.)

It's based on a concept from the AXD301. The idea is that
you have a permanent process that creates request threads.

The threads themselves are not gen_servers, but one could
easily make a gen_server-compatible "mdisp behaviour", such
that the thread can be programmed like a gen_server.

Just to show what the programming model would look like,
I've added an example behaviour. The callback module
implementing the behaviour needs to implement three
functions: init(Key, State), awake(Key, State),

Typically, a "port process" will receive messages from the
outside, do some partial decode, and then call

mdisp:new(MDisp, MDispBehaviour, Key, State)

Subsequent messages can be send to the new instance using

mdisp:send(MDisp, Key, Msg).

The threads can stay up until they're done, or go to sleep
during periods of inactivity (the sleep() function is highly
optimized and "thread safe").

I can submit the whole package (5K) if someone is really
eager to try it out.


-export([init/2, awake/2, terminate/3]).

%% internal exports
-export([f1/2, f2/2]).

-define(write(Fmt, Args), ok=io:format(Fmt, Args)).

init(Key, State = {Fun, S}) ->
    ?write("init(~p, ~p)~n", [Key, State]),
    ?MODULE:Fun(Key, S).

awake(Key, State = {Fun, S}) ->
    ?write("awake(~p, ~p)~n", [Key, State]),
    ?MODULE:Fun(Key, S).

terminate(Reason, Key, State) ->
    exit({Reason, {Key, State}}).

f1(Key, S) ->
    ?write("f1(~p)~n", [S]),
	Msg ->
	    ?write("f1 ==> ~p~n", [Msg]),
	    f2(Key, S+1)
    after 5000 ->
	    ?write("f1 going to sleep (~p)~n", [S]),
	    mdisp:sleep(mdisp, Key, {f1, S})

f2(Key, S) ->
    ?write("f2(~p)~n", [S]),
	this ->
	    ?write("f2 ==> ~p~n", [this]),
	    f1(Key, S+1)
    after 5000 ->
	    ?write("f2 going to sleep (~p)~n", [S]),
	    mdisp:sleep(mdisp, Key, {f2, S})

Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson Telecom AB, ATM Multiservice Networks

More information about the erlang-questions mailing list