zaz / CS-33211

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Producer-Consumer

This program implements the producer-consumer problem on a table in shared memory that holds 2 items and a semaphore.

Quick Start Guide

To watch the shared memory change as the program runs, run:

make watch

Or you can do the same thing manually by running

watch -n .2 xxd -e /dev/shm/producerConsumerTable

in one terminal and running

./producer 1.0 &
./consumer 1.0

in another. 1.0 sets the delay in the main loop of each program to 1s.

Memory Format

/dev/shm/producerConsumerTable contains 36 bytes:

  • 00-31: semaphore
  • 32-33: item 1
  • 34-35: item 2

Usage

./[consumer | producer] [delay [num_threads]]

After running make, run either ./producer or ./consumer. Both take optional arguments delay (default 0.01) and number of threads. If number of threads is specified, delay must be specified.

Program Structure

The program is composed of 3 files: producer.c, consumer.c, and shared.h, the latter of which contains functionality shared by both. In particular, shared.h contains a run function that accepts a function pointer as argument. producer.c and consumer.c define produceItem and consumeItem, respectively, and pass those functions to run along with the command-line arguments.

run calls initializeSharedMemory to open the shared memory table, parses optional arguments, and then creates num_threads threads (default 1) that each run the function passed to run.

Testing

Run make test to build and run both producer and consumer. Producer produces 14 items and exits. Consumer is killed after by Make after an appropriate delay. This is repeated up to 100 times, and if none match the expected output, the test fails. The reason for repeating is because the scheduler can cause some uncertainty in ordering. It is possible to mitigate this by running the programs with larger delays, but the current testing setup usually succeeds within a few loops, which is quicker than increasing the delay.

make test first tests with single threads, and then tests the case where producer and consumer each run with two threads.

Valgrind confirmed that no memory leaks are possible when the programs exit normally, but handling memory when the program is interrupted was not made robust.

Potential Improvements

  1. Restrict syscalls with SECCOMP for security.
  2. Ensure the mutex is released and all file descriptors are closed if the program is interrupted.
  3. Implement custom semaphores. <semaphore.h> is overkill for what we need and uses 32 bytes of memory!

About


Languages

Language:C 73.4%Language:Makefile 13.9%Language:Shell 12.6%