#include #include #include #include #define N 10 #define P 12 #define C 1 #define PSLEEP 5 #define CSLEEP 4 int buf[N], p[P], c[C], nt[P + C]; pthread_t tid[P + C]; int indPut, indGet, val; sem_t exclusbuf, exclusval, gol, plin; //afiseaza starea curenta a producatorilor si a consumatorilor void afiseaza() { int i; for (i=0; i < P; i++) printf("P%d_%d\t", i, p[i]); for (i=0; i < C; i++) printf("C%d_%d\t", i, c[i]); printf("B: "); for (i=0; i < N; i++) if (buf[i] != 0) printf("%d ", buf[i]); printf("\n"); fflush(stdout); } //rutina unui thread producator void* producator(void* nrp) { int indp = *(int*)nrp; for ( ; ; ) { sem_wait(&exclusval); val++; p[indp] = -val; // Asteapta sa depuna val in buf sem_post(&exclusval); sem_wait(&gol); sem_wait(&exclusbuf); buf[indPut] = -p[indp]; // A depus val in buf p[indp] = -p[indp]; afiseaza(); p[indp] = 0; // Elibereaza buf si doarme indPut = (indPut + 1) % N; sem_post(&exclusbuf); sem_post(&plin); sleep(1 + rand() % PSLEEP); } } //rutina unui thread consumator void* consumator(void* nrc) { int indc = *(int*)nrc; for ( ; ; ) { c[indc] = -1; // Asteapta sa scoata din buf sem_wait(&plin); sem_wait(&exclusbuf); c[indc] = buf[indGet]; // Scoate o valoare din buf buf[indGet] = 0; // Elibereaza locul din buf afiseaza(); c[indc] = 0; // Elibereaza buf si doarme indGet = (indGet + 1) % N; sem_post(&exclusbuf); sem_post(&gol); sleep(1 + rand() % CSLEEP); } } //functia principala main() { sem_init(&exclusbuf, 0, 1); sem_init(&exclusval, 0, 1); sem_init(&gol, 0, N); sem_init(&plin, 0, 0); int i; val = 0; indPut = 0; indGet = 0; for (i = 0; i < N; buf[i] = 0, i++); for (i = 0; i < P; p[i] = 0, nt[i] = i, i++); for (i=0; i < C; c[i] = 0, nt[i + P] = i, i++); for (i = 0; i < P; i++) pthread_create(&tid[i], NULL, producator, &nt[i]); for (i = P; i < P + C; i++) pthread_create(&tid[i], NULL, consumator, &nt[i]); for (i = 0; i < P + C; i++) pthread_join(tid[i], NULL); sem_destroy(&exclusbuf); sem_destroy(&exclusval); sem_destroy(&gol); sem_destroy(&plin); }