/****************************************/ /* */ /* Prof. Dr. Carsten Vogt */ /* TH Koeln, Fakultaet IME */ /* http://www.nt.th-koeln.de/vogt */ /* */ /* Linux-C-Schnittstelle mit pthreads: */ /* Erzeuger-Verbraucher-Problem */ /* mit Mutex und Bedingungsvariablen */ /* */ /****************************************/ // Unter Linux zu uebersetzen mit 'gcc -pthread ...' oder 'cc -pthread ...' #include #include #include #include #define PUFFERKAP 3 #define ERZZEIT 1 #define VBRZEIT 3 #define GESAMTLAUFZEIT 30 pthread_mutex_t mutex; pthread_cond_t cond_voll, cond_leer; int puffer[PUFFERKAP+1], lese_index, schreib_index; void print_puffer() { int i; if (lese_index==schreib_index) { printf(" Puffer leer\n"); return; } printf(" Pufferinhalt:"); if (lese_index Erzeuger blockiert\n"); pthread_cond_wait(&cond_voll,&mutex); } printf("Erzeuger: Schreiben beginnt\n"); sleep(1); puffer[schreib_index] = wert; wert += 10; incr_index(&schreib_index); print_puffer(); printf("Erzeuger: Schreiben endet\n"); pthread_cond_signal(&cond_leer); pthread_mutex_unlock(&mutex); } } void *verbraucher_loop(void *p) { while (1) { pthread_mutex_lock(&mutex); while (puffer_leer()) { printf("Puffer leer => Verbraucher blockiert\n"); pthread_cond_wait(&cond_leer,&mutex); } printf("Verbraucher: Lesen beginnt\n"); sleep(1); printf(" gelesen: %d\n",puffer[lese_index]); incr_index(&lese_index); print_puffer(); printf("Verbraucher: Lesen endet\n"); pthread_cond_signal(&cond_voll); pthread_mutex_unlock(&mutex); sleep(VBRZEIT); } } int main (int argc, char *argv[]) { pthread_t erzeuger, verbraucher; pthread_mutex_t mutex; int rc; rc = pthread_mutex_init(&mutex, NULL); printf("mutex_init(): return code = %d\n",rc); rc = pthread_cond_init(&cond_voll, NULL); printf("cond_init(cond_voll): return code = %d\n",rc); rc = pthread_cond_init(&cond_leer, NULL); printf("cond_init(cond_leer): return code = %d\n",rc); lese_index = 0; schreib_index = 0; pthread_create(&erzeuger, NULL, erzeuger_loop, NULL); pthread_create(&verbraucher, NULL, verbraucher_loop, NULL); sleep(GESAMTLAUFZEIT); pthread_cancel(erzeuger); pthread_cancel(verbraucher); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond_voll); pthread_cond_destroy(&cond_leer); }