In today's studio you will explore fork-join paralellism in combination with file and network IO.
Please complete the following required exercises. I encourage you to please work in groups of 2 or 3 people on each studio (and the groups are allowed to change from studio to studio) though if you would prefer to complete any studio by yourself that is also allowed.
As you work through these exercises, please record your answers, and when you finish them please log into Canvas, select this course in this semester, and then on the Canvas page for this studio assignment upload (1) a file containing your answers and (2) any code you produced while answering the exercises. Only one submission per team, please, and if you need to re-submit it the person who originally submitted the studio should please be the one to do that.
Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.
As the answer to the first exercise, list the names of the people who worked together on this studio.
Log in using ssh into shell.cec.wustl.edu
using your WUSTL
Key id and password, issue the qlogin
command to
get onto one of the Linux Lab machines, and then within the directory you
created for this course, add a new directory for this studio.
In that new directory, use the cargo new
command to create a new
package (named e.g., rustconcurrency
).
Change into the src
directory within that package and in
the main.rs
file that it contains modify the main
function
so that before the line println!("Hello, world!");
it spawns a child
thread that also uses println!
to print out a different text message.
Compile and run your program, and as the answer to this exercise please show the output that was produced.
Modify the main
function so that it stores the thread handle returned
by the spawn
call in a variable, and then at the bottom of the
main
function matches on the result of a call to the join
method on that variable.
Compile and run your program, and as the answer
to this exercise please show the output that was produced.
Modify the main
function so that it iterates through the command line
arguments that were passed to it, for each of those arguments except for the one
that holds the name of the program spawns a child thread
that prints out that argument, stores a handle to each thread in a vector, and
then at the bottom of the main
function matches on the result of a
call to the join
method on each handle in the vector.
Compile and run your program with multiple command line arguments, and as the answer to this exercise please show (1) the code in the main function, and (2) the output that was produced.
Modify the main
function so that each child thread treats the text
that was passed to it as the name of a file, and tries to open it in a buffered
reader. If successful the child thread should (as in the
previous studio) use the buffered reader's
lines
method to iterate through and print out each non-blank line of
the file (i.e., any line that has at least one non-whitespace token),
or if the file could not be opened, the child thread should print out a message
to that effect instead.
Compile and run your program with text identifying two files that exist, and two files that do not, as in:
cargo run Cargo.lock ../Cargo.lock Cargo.toml ../Cargo.tomlAs the answer to this exercise please show (1) the code in the main function, and (2) the output that was produced.
Please see the Networking pages at the end of Chapter 18 in the BOT text book, the TcpListener page, and the TcpStream page, for examples with the kind of code you'll need for this exercise.
Modify the main
function so that it declares a variable initialized
with the result of a call to TcpListener::bind
, spawns and then joins
with a thread that uses that variable to accept a TCP connection, reads and
prints out the text sent to it on the accepted connection, and then ends.
Between spawning that thread and joining with it, the main function should
establish a TCP connection by callling TcpStream::connect
with the same
address used in the call to TcpListener::bind
, send all of the
command line arguments over that connection, and then call the connection's
TcpStream::shutdown
method to close it.
Compile and run your program and as the answer to this exercise show (1) the code you wrote for this exercise, and (2) the new output that code produced.
Modify the thread that runs the TcpListener
so that it accepts and
uses connections repeatedly in a loop
. Compile and run your program
and confirm that the program does not terminate until you hit Ctrl-C in the terminal
window. As the answer to this exercise please explain briefly why the main thread
cannot end until the other thread exits its loop.
Above the main
function, declare a static flag of type
AtomicBool
that is initialized to false
. At the bottom
of the loop
you added in the previous exercise, have the thread check
the value of that flag and if it is true
the thread should
break
out of its loop
.
Modify the main
function so that immediately after it calls
TcpStream::shutdown
it sets the flag to true
and
then connects to the TcpListener
one more time (but does not do
anything with that connection before joining with the threads).
Compile and run your program and confirm that the program terminates normally.
As the answer to this exercise please explain briefly why it was necessary to make an
extra call to connect
after setting the flag.
For this studio, please turn in the following:
Page posted Saturday November 2, 2024, by Chris Gill.