CSE 542S: Studio 18

Concurrency


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.


Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.

  2. 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.

  3. 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.

  4. 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.

  5. 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.toml
    As the answer to this exercise please show (1) the code in the main function, and (2) the output that was produced.
  6. 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.

  7. 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.

  8. 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.

Things to Turn In:

For this studio, please turn in the following:


Page posted Saturday November 2, 2024, by Chris Gill.