posix 信号量---生产者消费者(二)

多个生产者一个消费者

#include "../unipc.h"

#define NBUFF 10
#define MAX_PRODUCE 10
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
int nitems;
int nproducers;
struct {
    int index;
    int buff[NBUFF];
    sem_t mutex,nempty,nstored;
} shared;

void *produce(void *arg)
{
    for(;;) {
        sem_wait(&shared.nempty);
        sem_wait(&shared.mutex);
        if(shared.index >= nitems){
            sem_post(&shared.nempty);
            sem_post(&shared.mutex);
            return NULL;
        }
        shared.buff[shared.index %NBUFF] = shared.index;
        shared.index++;
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);
        (*(int*)arg)++;       
    }
}

void *consume(void *arg)
{
    int i;
    for(i = 0;i < nitems; i++) {
        sem_wait(&shared.nstored);
        sem_wait(&shared.mutex);
        if(i != shared.buff[i%NBUFF]) {
            printf("i = %d,buff[%d]=%d\n",i,i,shared.buff[i]);
        }
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);
    }
    return NULL;
}

int main(int argc ,char *argv[])
{
    int i;
    int count[MAX_PRODUCE];
    pthread_t ptid_produce[MAX_PRODUCE],ptid_consume;

    if(argc != 3) {
        printf("usage produce3 <#produces> <#items>\n");
        return -1;
    }
    nproducers = atoi(argv[1]);
    nitems = atoi(argv[2]);
    if(nproducers > MAX_PRODUCE)
        nproducers = MAX_PRODUCE;
    printf("nproducers = %d,nitems=%d\n",nproducers,nitems); 
    sem_init(&shared.mutex,0,1);
    sem_init(&shared.nempty,0,NBUFF);
    sem_init(&shared.nstored,0,0);
    shared.index = 0;

    for(i = 0;i < nproducers; i++) {
        count[i] = 0;
        pthread_create(&ptid_produce[i],NULL,produce,&count[i]);
    }
    pthread_create(&ptid_consume,NULL,consume,NULL);

    for(i = 0;i < nproducers; i++) {
        pthread_join(ptid_produce[i],NULL);
        printf("count[%d] = %d\n",i,count[i]);
    }
    pthread_join(ptid_consume,NULL);

    sem_destroy(&shared.mutex);
    sem_destroy(&shared.nempty);
    sem_destroy(&shared.nstored);
    return 0;
}
生产者线程的终止

当最后一个条目生产出来后,每个生产者线程都执行循环顶端的语句:

sem_wait(&shared.nempty);

它将nempty信号量减1。然而每个生产者线程在终止前必须给该信号量加1,因为它在最后一次走过循环时并没有往缓存区存入一个条目。

 

你可能感兴趣的:(posix 信号量---生产者消费者(二))