by Example

Monitors


Monitors are an alternative to links. Unlike links, which are
bidirectional, monitors are unidirectional.










This worker will wait for ?TIMEOUT ms, and if it does not
receive any work it will die and a
`{'DOWN', Ref, process, PidOfTerminatedProc, Reason}`
message will be send to its monitors.









To monitor a process, use the function `erlang:monitor`
then listen for `DOWN` messages in the `receive` block.
Repeated calls to `erlang:monitor` will create several,
independent monitors.





























To remove a monitor call erlang:demonitor(Ref).










-module(monitors).
-compile([export_all]).
-define (TIMEOUT, 3000).


worker() ->
    receive
        do_work ->
            io:format("I (worker ~p) will work now~n", [self()]),
            worker()




    after ?TIMEOUT ->
        io:format("I (worker ~p) have no work to do~n", [self()]),
        io:format("I (worker ~p) will die now ...~n", [self()]),
        exit(no_activity)
    end.



parent() ->




    Pid = spawn(monitors, worker, []),
    register(worker, Pid),
    Reference = erlang:monitor(process, Pid),

    io:format("I (parent) have a new worker~p~n", [Pid]),
    ?MODULE ! {new_worker, Pid},
    receive
        {'DOWN', Reference, process, Pid, Reason} ->
            io:format("I (parent) My worker ~p died (~p)~n", [Pid, Reason]),
            parent()
    end.


loop() ->
    receive
        {new_worker, WorkerPid} ->
            timer:sleep(?TIMEOUT-2000),
            WorkerPid ! do_work,
            loop()
    end.


start() ->
    Pid = spawn(monitors, loop, []),
    register(?MODULE, Pid),

    ParentPid = spawn(monitors, parent, []),
    register(parent, ParentPid),


    Ref = erlang:monitor(process, Pid),
    erlang:demonitor(Ref),

    timer:sleep(round(?TIMEOUT*1.5)),
    exit(whereis(worker), finished),
    exit(whereis(parent), finished),
    exit(whereis(?MODULE), finished),
    ok.

1> c(monitors).
{ok,monitors}

2> monitors:start().
I (parent) have a new worker<0.64.0>
I (worker <0.64.0>) will work now
I (worker <0.64.0>) have no work to do
I (worker <0.64.0>) will die now ...
I (parent) My worker <0.64.0> died (no_activity)
I (parent) have a new worker<0.65.0>
ok


Next: List Comprehension