Laboratory Exercises For Computer Science 213

Shared Memory and Process Synchronization in Linux

Shared Memory and Process Synchronization in Linux:

Summary: This laboratory exercise provides practice with shared memory and process synchronization in Linux.

Preparation

  1. Review sample programs 7-9 in An Introduction to Concurrency in Unix-based [GNU] C Through Annotated Examples, as discussed in class.

  2. Review the corresponding Linux-based programs (read-write-1.c through read-write-3.c) distributed in class.

Experiments with Shared Memory

  1. Copy ~walker/c/concurrency-linux/read-write-1.c and ~walker/c/concurrency-linux/temp.file to your account, compile it with gcc, and run it a few times. Describe the output you get, and explain briefly how it is produced.

  2. Examine temp.file, and then run read-write-1.c. Is temp.file modified by the program? (It is not supposed to be according to Unix and Linux documentation.)

  3. In the class handouts, the open statement referenced file /home/walker/c/concurrency-linux/temp.file, while the version for this lab references a local file temp.file. Can you think of a reason why this change is made in read-write-1.c for this lab?

  4. Remove the sleep statement from the child process, rerun read-write-1.c, and explain the output produced.

  5. Restore the sleep statement from the previous step, and remove it from the parent process. Again, rerun read-write-1.c, and explain the output produced.

  6. Rather than rely upon sleep statements to synchronize the two processes, consider the use of spinlocks. In this approach, the parent will write to shared memory when the memory location contains the value -1, and the child will read when the memory location is not -1.

    1. Initialize the shared memory location in main memory to -1 before the fork operation. (Why must this be done before the fork?)
    2. Replace the sleep statement for the child by a spinlock that checks that the shared memory contains a nonnegative value. At the end of the child's loop, the shared memory location should be reset to -1.
    3. Remove the sleep statement from the parent at the end of the loop, and insert a spinlock at the beginning of the loop that checks that memory is -1. When this condition occurs, the parent may write the next nonnegative number to shared memory.

  7. Copy programs ~walker/c/concurrency-linux/read-write-2a.c, ~walker/c/concurrency-linux/Mmap-include.c, and ~walker/c/concurrency-linux/read-write-2b.c to your account. Then, compile read-write-2a.c and read-write-2b.c with gcc, run them a few times, and review the code to be sure you understand how the programs work.

  8. Explain whether read-write-2b.c will work when there are multiple readers or when there are multiple writers. In each case, if the code would work, explain why. If the code would not work, give a timing sequence involving the several readers and/or writers showing what might go wrong.

Experiments with Semaphores

  1. Copy ~walker/c/concurrency-linux/read-write-3.c, to your account, compile it with gcc and run it.

  2. Review read-write-3.c to be sure you understand how it works.

  3. Use the idea of semaphores, as implemented in read-write-3.c, in place of the spinlocks in Step 8 to handle the synchronization of the reader and write process from read-write-1.c. Your final program should not use either spinlocks or sleep statements.

  4. With this use of semaphores, explain whether your code in step 13 will work when there are multiple readers or when there are multiple writers. In each case, if the code would work, explain why. If the code would not work, give a timing sequence involving the several readers and/or writers showing what might go wrong.


Work to be turned in:

Note: For steps 8 and 13, use the format for submitting assignments for each program.


This document is available on the World Wide Web as

     http://www.cs.grinnell.edu/~walker/courses/213.fa00/lab-semaphores.html

created October 7, 2000
last revised October 9, 2000