多个生产者,单个消费者,信号量
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define min(a,b) ((a)<(b)?(a):(b)) #define NBUFF 10 #define MAXNTHREADS 100 int nitems, nproducers; struct { int buff[NBUFF]; int nput, nputval; sem_t mutex, nempty, nstored; }shared; void *produce(void *), *consume(void *); int main(int argc, char **argv) { int i, count[MAXNTHREADS]; pthread_t tid_produce[MAXNTHREADS], tid_consume; if(argc!=3) { fprintf(stderr, "./a.out <#items> <#producers>\n"); exit(-1); } nitems=atoi(argv[1]); nproducers=min(atoi(argv[2]), MAXNTHREADS); sem_init(&shared.mutex, 0, 1); sem_init(&shared.nempty, 0, NBUFF); sem_init(&shared.nstored, 0, 0); pthread_setconcurrency(nproducers+1); for(i=0;i<nproducers;i++) { count[i]=0; pthread_create(&tid_produce[i], NULL, produce, &count[i]); } pthread_create(&tid_consume, NULL, consume, NULL); for(i=0;i<nproducers;i++) { pthread_join(tid_produce[i], NULL); printf("count[%d]=%d\n", i, count[i]); } pthread_join(tid_consume, NULL); sem_destroy(&shared.mutex); sem_destroy(&shared.nempty); sem_destroy(&shared.nstored); exit(0); } void *produce(void *arg) { for(;;) { sem_wait(&shared.nempty); sem_wait(&shared.mutex); if(shared.nput>=nitems) { sem_post(&shared.nempty); sem_post(&shared.mutex); return NULL; } shared.buff[shared.nput%NBUFF]=shared.nputval; shared.nput++; shared.nputval++; sem_post(&shared.mutex); sem_post(&shared.nstored); *((int *)arg) += 1; } return NULL; } void *consume(void *arg) { int i; for(i=0;i<nitems;i++) { sem_wait(&shared.nstored); sem_wait(&shared.mutex); if(shared.buff[i%NBUFF]!=i) { printf("buff[%d]=%d\n", i%NBUFF, shared.buff[i%NBUFF]); } sem_post(&shared.mutex); sem_post(&shared.nempty); } return NULL; }
运行结果如下:
$ ./a.out 1000000 6 count[0]=619 count[1]=23982 count[2]=263473 count[3]=208842 count[4]=241089 count[5]=261995