Recent Changes - Search:

Meeting Signup

Sections

Projects

edit SideBar

P5

Programming homework 5: Threads Synchronization

Due Date: Thursday, May 7 at 9pm

You are to do this project BY YOURSELF.

This project must be implemented in C.

Updates

  • Thursday, May 7th: Several people have asked about why insert_item() and remove_item() can return an error. This is for sound software engineering, not because your implementation will actually return errors. The only time these functions should return an error is if (a) they use dynamic memory allocation and they fail to allocate memory, or (b) you implement logic to terminate the threads when the program is shutting down, and the functions return without inserting or removing in this case. They should not return -1 just because the buffer is full or empty.
  • Thursday, May 7th. In response to questions, here are a few clarifications. First, the optional part is not extra credit, it is just extra fun. Second, the bounded buffer should ideally be a circular buffer/queue, so that items are removed in the same order they are added.
  • Wednesday, May 6th: Here is a link to documentation on using semaphores in Linux.
  • Monday, May 4th: Someone asked about names for the programs. You should name the executable for the first program sem-sync and the executable for the second one (condition variables) cond-sync.
  • Sunday May 3rd: you should limit the random sleep to 10 seconds if you use sleep(). Ideally, you should use usleep() and limit it to one second.

Goals

  • To get experience with thread synchronization using condition variables and semaphores

Outline

This is project 6.40 from the book. You will implement a simple producer/consumer style of communication using a bounded buffer. For fun, you get to implement this both with semaphores and condition variables.

The buffer you will use is simple:

  typedef int buffer_item;
  #define BUFFER_SIZE 5

You will implement two functions: insert and remove

  buffer_item buffer[BUFFER_SIZE];

  int insert_item(buffer_item item) {
    /* insert an item into buffer, block until space available */
    return 0 if successful, otherwise
    return -1 if unsuccessful, such as memory allocation fails
  }

  int remove_item(buffer_item *item) {
    /* remove an item into buffer */
    return 0 if successful, otherwise
    return -1 if unsuccessful, such as memory allocation fails
  }

The main function is simple. It takes three paramters:

  1. Number of seconds to sleep before terminating
  2. Number of producer threads
  3. number of consumer threads

The outline of the main function is:

  int main(int argc, char * argv[]) {
    /* 1. get cmd line arguments */.
    /* 2. Initialize buffer */
    /* 3. Create producer threads */
    /* 4. Create consumer threads */
    /* 5. Sleep */
    /* 6. Exit */
  }

The producer and consumer threads are simple:

  void * producer(void * param) {
    buffer_item item;
    while (TRUE) {
      /* sleep a random time period */
      sleep (...);
     /* generate a random item */
     item = rand();
     if (insert_item(item)) == -1) {
       fprint(stderr,"Report error condition\n");
     } else {
       printf("Producer produced %d\n",item);
     }
   }
  }

 void * consumer(void * param) {
    buffer_item item;
    while (TRUE) {
      /* sleep a random time period */
      sleep (...);
     /* generate a random item */
     if (remove_item(&item)) == -1) {
       fprint(stderr,"Report error condition\n");
     } else {
       printf("Consumer consumed %d\n",item);
     }
   }
  }

You need to fill in the missing code in the main function and add appropriate synchronization code to the insert/remove item functions.

Part 1: Semaphores

Implement the bounded buffer using only sempahores (not semaphores and mutexes).

Part 2: Condition variables

Implement this code using mutex locks and condition variables.

Part 3: Optional

Implement a pipeline of three stages: an initial producer, a consumer/producer to another buffer, and a final consumer. You may use either semaphores or condition variables.

Resources

Compiling a multi-threaded program with POSIX threads on Linux requires two things. First, you need to include the pthread header file pthread.h in your code. Second, when compiling, you need to link with the pthread library -lpthread . That's about it.

What to turn in

Please turn in your source code and a makefile that builds both programs to ~cs537-1/handin/<your login>/p5.

Edit - History - Print - Recent Changes - Search
Page last modified on May 07, 2009, at 03:26 PM