[erlang-questions] newbie: how to clear a mailbox of a process?

Adam Lindberg adam@REDACTED
Mon Jan 28 14:49:49 CET 2008


Hi,

My answers to your questions are:

1) Is it possible to force clearance of a process's mailbox?

Well, force is maybe the wrong word, because you do it manually. The way to
clear the process mailbox is to run a receive loop which throws away all
existing messages:

clear_mailbox() ->
    receive
        _Any ->
            clear_mailbox()
    after 0 ->
        ok
    end.

2) What is the usual 'pattern' for implementation of a
voting/committee algorithm?

I don't know if there's any usual pattern, but I think your approach is
fine. What you could do is to spawn one new process which in turn spawn all
the voters. This way you can just kill that process once one negative vote
has come in so that you don't have to empty the mailbox.

3) For testing I want to run the script noninteractively using command
line e.g. "/opt/erlang/otp-R12B-0/bin/erl  -run p3 isprime 7 -s init
stop -noshell" but I cannot get it to work. (I am getting badarith
exception and core dump. Did I miss some parameters in the command
line?

The number seven provided on the command line is most likely the string "7".
You need to provide a function header which can take strings as arguments if
you want that to work. For example:

isprime(S) when is_list(S) ->
    isprime(string:to_integer(S)).

4) If I made some obvious programming mistakes, please feel free to point
out

If you would find a divider before you spawned all the voter processes, they
would still continue spawning. It's kind of pointless for large numbers to
spawn all the voters even if one of them fail. You should partition your
execution so that you can stop as soon as you found a negative.

One other thing one can question is the use of exits as messages. The usual
way to do it is to spawn a process that sends a message back to its creator.
This way, trapping exits and all, you obscure any real errors that could
occur. It is better to spawn the processes with the arguments Parent (where
Parent is a pid), N and Div and then instead of "exit(...)" do "Parent !
divisible | non_divisible".

For example:
...
lists:map(
    fun(Div) ->
        spawn_link(
            fun() ->
                test_if_divisible(self(), N, Div)
            end)
    end, C),
...
test_if_divisible(Parent, N, Div) ->
    case N rem Div of
        0 -> Parent ! divisible;
        _ -> Parent ! nondivisible
    end.


Cheers!
Adam

On Jan 28, 2008 1:54 PM, Anthony Kong <anthony.hw.kong@REDACTED> wrote:

> Hi, all,
>
> Sorry, I don't think the subject line makes much sense. Hopefully if
> you read on, the example may speak for itself.
>
> I have again written a simple script:
>
> =======
>
> -module(p3).
> -export([isprime/1, test_if_divisible/2]).
>
> isprime(2) ->
>  true;
>
> isprime(N) when N > 2 ->
>  C = lists:seq(2, N - 1),
>  process_flag(trap_exit, true),
>  lists:map(fun(Div) -> spawn_link(fun() -> test_if_divisible(N, Div)
> end) end, C),
>  isprime_poll(length(C)).
>
>
> isprime_poll(0) ->
>  true;
> isprime_poll(NumVote) ->
>  receive
>    {'EXIT', _Pid, nondivisible} ->
>        isprime_poll(NumVote - 1);
>    {'EXIT', _Pid, divisible} ->
>        false
>  end.
>
>
> test_if_divisible(N, Div) ->
>  case N rem Div of
>    0 -> exit(divisible);
>    _ -> exit(nondivisible)
>  end.
> =======
>
> The idea of this script are
> 1) in order to check if a number, says N, is a prime or not, the
> script will fire a process to test divisibility by each possible
> divisor (in the range of 2 to N - 1)
> 2) these processes are 'voting': if all these processes vote that N is
> not divisible, then N is a prime
> 3) I want to short circuit the voting process by looking for
> 'non-divisible' exit message. If I got one, the isprime_poll/1 will
> abort the tail-recursion and return false
>
> So, if I run the following tests, they produces results as expected,
> *provided* that I do not run them in one go:
>
> 2> p3:isprime(6).
> false
> ...
> (abort... then start erl again)
> ...
> 2> p3:isprime(7).
> true
>
>
> If I run like these 2 statements in the same shell, however, then what
> I got is a wrong answer for 7.
>
> 1> l(p3).
> {module,p3}
> 2> p3:isprime(6).
> false
> 3> p3:isprime(7).
> false
> 4> p3:isprime(7).
> true
>
> I believe it is because that while I make isprime_poll/1 return false
> on first 'nondivisible' message, those remaining messages sent from
> other processes are still in the mailbox. So if I immedately run
> isprime(7) after isprime(6), it'll take in these messages from last
> session and hence make a wrong conclusion.
>
> So, here is my questions:
>
> 1) Is it possible to force clearance of a process's mailbox?
> 2) What is the usual 'pattern' for implementation of a
> voting/committee algorithm?
> 3) For testing I want to run the script noninteractively using command
> line e.g. "/opt/erlang/otp-R12B-0/bin/erl  -run p3 isprime 7 -s init
> stop -noshell" but I cannot get it to work. (I am getting badarith
> exception and core dump. Did I miss some parameters in the command
> line?
> 4) If I made some obvious programming mistakes, please feel free to point
> out
>
> Cheers,
>
> Anthony
>
>
>
>
>
> --
> /*--*/
> Don't EVER make the mistake that you can design something better than
> what you get from ruthless massively parallel trial-and-error with a
> feedback cycle. That's giving your intelligence _much_ too much
> credit.
>
> - Linus Torvalds
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080128/e4e3fabf/attachment.htm>


More information about the erlang-questions mailing list