多个生产者,单个消费者,信号量

#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
posted @ 2022-10-12 15:03  东宫得臣  阅读(18)  评论(0编辑  收藏  举报