In your group you are going to do the following:
- On paper, come up with a PSEUDOCODE solution to synchronize the
actions of Producer and Consumer
threads that add and remove items to a shared, fixed-capacity buffer:
- Some number of Producer threads, each in a loop forever:
- produce the next item
- add it to the shared buffer (to one end of a circular queue)
- Some number of Consumer threads, each in a loop forever:
- remove the next item from the front of the buffer
- consume it
Some questions to consider:
- are there actions that need to be made atomic
(require mutually exclusive access)?
- are there any scheduling types of synchronization necessary?
- what synchronization primitives do you need?
and how are they used (by whom and when)?
- is any other state needed to synchronize the actions of threads?
You may assume:
- The following shared global buffer state has been declared:
static char *buff; // the buffer
static int N; // total buffer capacity
static int size; // current num items in the buffer
static int next_in; // next insertion index in the buffer
static int next_out; // next remove index in the buffer
static int num_items; // number of items each tid should produce or consume
- There exist functions to add and remove items to the buffer as
a circular queue (add to one end, remove from the other).
void add_to_queue(char item);
item remove_from_queue();
These functions have no synchronization, nor do they check if there is space
on an add or something to remove on a remove. They just add or remove
to buff in a circular fashion and update other state variables as a
result of their actions.
- Some pthread functions:
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_cond_wait(&mycond, &mutex);
pthread_cond_signal(&mycond);
pthread_barrier_init(&mybarrier, NULL, numtids);
pthread_barrier_wait(&mybarrier);
- When you are happy with your pseudocode algorithm talk Tia or Bryce
or Ryerson through your algorithm BEFORE MOVING ON TO THE NEXT STEP.
.
- Try implementing your pseudocode solution in pthreads.
Copy over starting point pthread code:
cd cs31/inclass
cp -r ~/cs31/inclass/13 .
cd 13
make
./prodcons 8 100 10
8 Producer and Consmer tids, each producing 100 items, buff size 10
There are already routines to add and remove items from the circular
buffer, and a debug print_buffer function (call fflush(stdout) after
any debug output to force it to the terminal window).
- Implement code in main to spawn producer and consumer tids
- Implement the producer and consumer main loop functions
- Add all synchronization necessary to synchronize the actions of
concurrent producer and consumer threads
Look at the man pages for pthread functions:
man pthread_create
man pthread_join
man pthread_cond_init
man pthread_mutex_init
- Before the end of class, share your joint solution with your team mates.
Here is one way to do this from the cs machine you are ssh'ed into:
% mail username1 < prodcons.c
% mail username2 < prodcons.c