#include #include #include #include #define BUFFERLENGTH 80 #define MAX_THREADS 1000 pthread_mutex_t mutex; pthread_cond_t cond; char *buffer; int currentReaders = 0; int writersExecuting = 0; int returnValue; /* not used; need something to keep compiler happy */ /* creates a new thread with default arguments*/ void create_thread(void * (*start_routine)(void*), void *args) { pthread_t *newThread; int result; newThread = malloc (sizeof (pthread_t)); if (!newThread) { fprintf (stderr, "Couldn't allocate memory for thread!\n"); exit (1); } result = pthread_create (newThread, NULL, start_routine, args); if (result != 0) { fprintf (stderr, "Thread creation failed!\n"); exit (1); } } /* the readers */ void *readersThread (void *args) { pthread_mutex_lock (&mutex); while (writersExecuting > 0) { pthread_cond_wait (&cond, &mutex); } currentReaders ++; pthread_mutex_unlock (&mutex); /* now do the reading */ /* use the buffer-variable without modifying it */ pthread_mutex_lock (&mutex); currentReaders --; pthread_cond_broadcast (&cond); pthread_mutex_unlock (&mutex); return (&returnValue); } /* the writers */ void *writersThread (void *args) { pthread_mutex_lock (&mutex); while ((writersExecuting > 0) || (currentReaders > 0)) { pthread_cond_wait (&cond, &mutex); } writersExecuting ++; pthread_mutex_unlock (&mutex); /* now do the writing */ /* modify the buffer in an appropriate way */ /* and release the lock */ pthread_mutex_lock (&mutex); writersExecuting --; pthread_cond_broadcast (&cond); pthread_mutex_unlock (&mutex); return (&returnValue); } int main () { void * args = NULL; int threadNo; char *command; pthread_mutex_init (&mutex, NULL); buffer = malloc (BUFFERLENGTH); if (!buffer) { fprintf (stderr, "Memory allocation failed!\n"); exit (1); } while (1) { if (threadNo > MAX_THREADS) { fprintf (stderr, "Number of threads exceeded, exiting!\n"); exit (0); } command = malloc (BUFFERLENGTH); if (!command) { fprintf (stderr, "Memory allocation failed!\n"); exit (1); } command = fgets (command, BUFFERLENGTH -1, stdin); switch (command[0]) { case 'W': threadNo ++; create_thread (writersThread, (void *) args); break; case 'R': threadNo ++; create_thread (readersThread, (void *) args); break; default: fprintf (stderr, "Wrong command %s detected, ignoring!\n", command); break; } } }