Hi,<br><br>My answers to your questions are:<br><br>1) Is it possible to force clearance of a process's mailbox?<br><br>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:<br>
<br><span style="font-family: courier new,monospace;">clear_mailbox() -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> receive</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> _Any -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> clear_mailbox()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> after 0 -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ok</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> end.</span><br><br>2) What is the usual 'pattern' for implementation of a<br>voting/committee algorithm?<br><br>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.<br>
<br>3) For testing I want to run the script noninteractively using command<br>line e.g. "/opt/erlang/otp-R12B-0/bin/erl -run p3 isprime 7 -s init<br>stop -noshell" but I cannot get it to work. (I am getting badarith<br>
exception and core dump. Did I miss some parameters in the command<br>line?<br><br>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:<br>
<br><span style="font-family: courier new,monospace;">isprime(S) when is_list(S) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> isprime(string:to_integer(S)).</span><br>
<br>4) If I made some obvious programming mistakes, please feel free to point out<br><br>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.<br>
<br>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". <br>
<br>For example:<br><span style="font-family: courier new,monospace;">...</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">lists:map(</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> fun(Div) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> spawn_link(</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> fun() -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> test_if_divisible(self(), N, Div)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> end)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> end, C),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">...</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">test_if_divisible(Parent, N, Div) -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> case N rem Div of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> 0 -> Parent ! divisible;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> _ -> Parent ! nondivisible</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> end.</span><br><br><br>Cheers!<br>
Adam<br><br><div class="gmail_quote">On Jan 28, 2008 1:54 PM, Anthony Kong <<a href="mailto:anthony.hw.kong@gmail.com">anthony.hw.kong@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi, all,<br><br>Sorry, I don't think the subject line makes much sense. Hopefully if<br>you read on, the example may speak for itself.<br><br>I have again written a simple script:<br><br>=======<br><br>-module(p3).<br>
-export([isprime/1, test_if_divisible/2]).<br><br>isprime(2) -><br> true;<br><br>isprime(N) when N > 2 -><br> C = lists:seq(2, N - 1),<br> process_flag(trap_exit, true),<br> lists:map(fun(Div) -> spawn_link(fun() -> test_if_divisible(N, Div)<br>
end) end, C),<br> isprime_poll(length(C)).<br><br><br>isprime_poll(0) -><br> true;<br>isprime_poll(NumVote) -><br> receive<br> {'EXIT', _Pid, nondivisible} -><br> isprime_poll(NumVote - 1);<br>
{'EXIT', _Pid, divisible} -><br> false<br> end.<br><br><br>test_if_divisible(N, Div) -><br> case N rem Div of<br> 0 -> exit(divisible);<br> _ -> exit(nondivisible)<br> end.<br>=======<br>
<br>The idea of this script are<br>1) in order to check if a number, says N, is a prime or not, the<br>script will fire a process to test divisibility by each possible<br>divisor (in the range of 2 to N - 1)<br>2) these processes are 'voting': if all these processes vote that N is<br>
not divisible, then N is a prime<br>3) I want to short circuit the voting process by looking for<br>'non-divisible' exit message. If I got one, the isprime_poll/1 will<br>abort the tail-recursion and return false<br>
<br>So, if I run the following tests, they produces results as expected,<br>*provided* that I do not run them in one go:<br><br>2> p3:isprime(6).<br>false<br>...<br>(abort... then start erl again)<br>...<br>2> p3:isprime(7).<br>
true<br><br><br>If I run like these 2 statements in the same shell, however, then what<br>I got is a wrong answer for 7.<br><br>1> l(p3).<br>{module,p3}<br>2> p3:isprime(6).<br>false<br>3> p3:isprime(7).<br>false<br>
4> p3:isprime(7).<br>true<br><br>I believe it is because that while I make isprime_poll/1 return false<br>on first 'nondivisible' message, those remaining messages sent from<br>other processes are still in the mailbox. So if I immedately run<br>
isprime(7) after isprime(6), it'll take in these messages from last<br>session and hence make a wrong conclusion.<br><br>So, here is my questions:<br><br>1) Is it possible to force clearance of a process's mailbox?<br>
2) What is the usual 'pattern' for implementation of a<br>voting/committee algorithm?<br>3) For testing I want to run the script noninteractively using command<br>line e.g. "/opt/erlang/otp-R12B-0/bin/erl -run p3 isprime 7 -s init<br>
stop -noshell" but I cannot get it to work. (I am getting badarith<br>exception and core dump. Did I miss some parameters in the command<br>line?<br>4) If I made some obvious programming mistakes, please feel free to point out<br>
<br>Cheers,<br><br>Anthony<br><br><br><br><br><br>--<br>/*--*/<br>Don't EVER make the mistake that you can design something better than<br>what you get from ruthless massively parallel trial-and-error with a<br>feedback cycle. That's giving your intelligence _much_ too much<br>
credit.<br><br>- Linus Torvalds<br>_______________________________________________<br>erlang-questions mailing list<br><a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br><a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div><br>