Sharing data

In this assignment you'll explore various data sharing schemes using threads and processes. In particular, you'll be experimenting with
  1. shared memory and semaphores with processes
  2. mutexes and conditional variables with threads
You will be using the producer/consumer problem as the vehicle of exploration.

Producer/consumer problem

There are two producers and one consumer.

Each producer reads its input file one character at a time and writes it into a shared buffer. The producer also sleeps for a while between successive writes. The buffer has a fixed size. The consumer consumes characters from this buffer one at a time and writes them into output files. The consumer writes all alphabets ('a-z' and 'A-Z') into one file and other characters into another file. The consumer also sleeps for a certain time between successive reads.

You will be implementing two versions of this problem.

  1. Using processes for producer and consumer. The synchronization should be done using semaphores.
  2. Using threads for producer and consumer. The synchronization should be done using mutexes and conditional variables.

Producer/consumer using processses

The producers and consumer should be different processes. The buffer which the processes see is implemented using shared memory. Accesses to the shared memory is controlled by semaphores. The following code skeleton illustrates a possible solution.
allocate shared memory
allocate semaphores
if (fork()) producer(); // producer 1
if (fork()) producer(); // producer 2
consumer();
complete the copy
deallocate IPC resources

The code implementing the producer-consumer problem should be in a file pcProcess.c.

Producer/consumer using threads

You should solve the producer-consumer problem using POSIX threads. In this case, the buffer is just a global variable. Mutexes and conditional variables can be used to control access to the shared buffer.

The threads version should be in the file pcThreads.c.

Program input/output

This program depends on the following parameters.
inputFile1:
The file the producer 1 reads
inputFile2:
The file the producer 2 reads
alphaOutputFile:
The file the consumer writes alphabets
nonAlphaOutputFile:
The file the consumer writes other characters
prod1Delay:
The sleep time (in microseconds) for the producer 1 between successive reads.
prod2Delay:
The sleep time (in microseconds) for the producer 2 between successive reads.
consDelay:
The sleep time (in microseconds) for the consumer between successive writes.
bufSize:
The size of the shared buffer.
The program should read these parameters from the file pars.dat in the current directory. These parameters are listed in the file, each parameter on a single line. You can find example files in the directory /home/solaris/ieng9/cs120s/public/p2/.

Note

  1. You can use usleep or nanosleep as your sleep function. Sleeping should be done outside the critical section.
  2. Test your code with "small" input files (size 10-20 bytes).

What to submit?

You should tar all your source files and the Makefile which compiles them. The name of the tar file should be pc.tar. Use bundleP2 to submit the code before 11:59 PM on May 05, 2000.

Report

Your report should address the following issues.
Programming models
Which programming model is more natural for application programs? Which model is natural for system programs? You should address sharing and synchronization constructs.
Efficiency
You can time the execution of the two versions for identical values of parameters and compare.
Security
Which model has better security? In other words, in which model can a rogue process/thread can do maximum damage?
Message passing
Message passing is another IPC technique. Discuss the advantages and disadvantages of message queues. You should look at the documentation of message queues. (man pages: msgget, msgsnd, msgrcv, etc.)
Other issues
The report along with self-evaluation report should be submitted to Allen Chu during his office hours on May 05, 2000.

Resources

  1. chooseID.c: An example program which uses shared memory and semaphores. There are two proceses which continuously choose globally unique IDs.
  2. POSIX threads tutorial: Read sections on "Resource locking" and "Conditional Variables".
  3. man pages: semget, shmget, ipcs, ipcrm, pthreads, etc.
  4. Section 12.1
  5. Class notes

Important

Semaphores and shared memory are global resources for the whole system. You should make sure that the allocated resorces are deleted before you logout. You can ensure this in three ways.
  1. Explicitly deleting the resources in the program itself as shown in the above example code.
  2. By deleting before logging out using ipcrm command. You can list the allocated resource using ipcs. This shows the resource ID (second field). Use ipcrm to delete all resources which are owned by you. Make sure you delete both shared memory and semaphores.
  3. By executing the script /home/solaris/ieng9/cs120s/public/bin/ipckill. You can create the file .logout in your home directory with the content /home/solaris/ieng9/cs120s/public/bin/ipckill. This ensures that all your IPC resources are deleted on logout. YOU SHOULD HAVE A ".logout" FILE IN YOUR HOME DIRECTORY WITH THE ABOVE COMMAND.