Explore concurrent programming in Erlang.
Beginning of class session 33.
ErlangHomework
folder. Within the folder are a couple of new files that you will use for this homework.
creation.erl
.
benchmark/1
function works.
On a Windows box, you do this by editing the shortcut for Erlang. Edit the properties of the shortcut so that the Target is like:
"C:\Program Files\erl5.6.2\bin\werl.exe" +P 250000
Do not change the text between the quotes from what it currently is on your machine. Add the +P 250000
after the closing quote.
+P <limit>
option. For example: $ erl +P 250000
erlang:system_info(process_limit).
Implement a function benchmark/0
to generate a table of benchmark information for N
values of 1000, 2000, 5000, 10,000, 20,000, 50,000, 100,000 and 200,000. The table should show the value of N
, the “wall clock” time used total and per process, and the processor time used total and per process for each case. See the documentation for the io
module for help on the io:format
function.
Here’s example output on my machine using just a single core:
CPU Time Clock Time N Tot (s) Per (ms) Tot (s) Per (ms) 1000 0.000 0.000 0.006 0.006 2000 0.010 0.005 0.010 0.005 5000 0.020 0.004 0.020 0.004 10000 0.030 0.003 0.040 0.004 20000 0.060 0.003 0.078 0.004 50000 0.160 0.003 0.209 0.004 100000 0.320 0.003 0.430 0.004 200000 0.660 0.003 0.935 0.005
On my machine, the CPU time per process when using two cores is nearly 6 times higher than when using a single core. Why might that be? If you have a multicore CPU, you can use the +S
n argument to erl
or werl
to tell Erlang to use n schedulers. Set this to 1 to run Erlang on a single core.
passing.erl
.
ring_part_loop/1
. You'll be adding several message patterns to the receive
block there.
ring_part_loop/1
so it handles a message {new_next, Pid}
by passing Pid
to the recursive call rather than NextProcessPid
as in the _Unknown
case.
Write a function spawn_ring(N)
(and any necessary helper functions) that spawns N processes using ring_part_loop/1
. It should use appropriate arguments or message sends to those processes to configure them in a ring as shown in the figure below. Your spawn_ring(N)
should return the process ID of one process in the ring.
Modify ring_part_loop/1
so it handles a message {relay, String, …}
, where String
is some message text and the …
is left for you to decide.
Design your message structure and code so that the relay
message is sent around the ring one full loop. When the message returns to the first process in the ring, that process should print the message String
.
During the course of relaying the message you may choose to modify the “…
” part of the message.
Modify ring_part_loop/1
so the relay message includes a value M like {relay, String, M, …}
, where String
is again some message text, M
is the number of circuits the message should make around the ring, and the …
is again left for you to decide.
Modify your message structure and code so that the relay
message is sent around the ring M full loops. When the message returns to the originating process after the Mth loop, that process should print the message String
and stop relaying the message.
relay
message to include an Originator process ID. This originator process ID will belong to some process not in the ring and won't change as the message goes around the loop. In ring_part_loop/1
, rather than printing the message String
, change your code to send the message back to the originator, like this: Originator ! String
Turn in your work by committing it to your SVN repository.