#include #include #include // producer-consumer program illustrating pthread synchronization // Shared circular queue for read/write. It's declared globally for // easy access by different threads. Of course we can also pass pointers // to shared structs, but that's just more code. // Producer threads write to buffer and blocks when buffer is full. // Consumer threads read from buffer and blocks when buffer is empty. // globally shared 1K buffer: #define QCAP 1024 int buffer[QCAP]; int front = 0; // index of first value in buffer (picture on left end) int size = 0; // current size of buffer. int back() { return (front+size) % QCAP; } // index of last value+1 int right(int i) { return (i+1)%QCAP; } // index to the "right" of index i int left(int i) { return (i+QCAP-1)%QCAP; } // index to the "left" of i void enqueue(int x) // add to back { buffer[back()] = x; size++; } int pop() // take from front { int ax = (int)buffer[front]; front = right(front); size--; return ax; } pthread_mutex_t synch; pthread_cond_t consume; // producers and consumers block on separate pthread_cond_t produce; // conditions. /* A thread has three principal states: running, blocked and ready. Blocked means the thread is waiting for some condition to become true. Ready means that the condition is met, and the thread now wants to run, but it may not run immediately, usually because it hasn't acquired a mutex (passed pthread_mutex_lock). When a thread calls pthread_cond_wait(pthread_cond_t*,pthread_mutex_t*) the thread releases the specified mutex and "blocks" on the condition queue. This call is equivalent to calling wait() inside a synchronized method in java, except here the synchronization is controlled by the mutex. When a thread calls pthread_cond_signal(pthread_cond_t*) one thread that's blocked on the specified condition queue is placed in the ready state, but will not run until it acquires the mutex that it blocked on. In other words, implicitly the released thread will call pthread_mutex_lock again. Usually, signal is called by a thread that already holds the mutex (passed lock). Such a call is equivalent to calling notify() inside a synchronized method in java pthread_cond_broadcast(pthread_cond_t*) unblocks all threads waiting on the condition and equivalent to calling notifyAll() in java. Usually, pthread_cond_wait/signal/broadcast is called while the thread is holding a mutex (between pthread_mutex_lock and pthread_mutex_unlock): this corresponds to calling the equivalent operations inside synchronized methods in java. */ int runs = 10; // number of times each producer and consumer will loop. // producer simulation thread function void * producetf(void * info) { int id = *(int*)info; // thread id - as determined by software printf("producer %d started..\n",id); for(int r=0;r