多线程编程系列(五):“生产者消费者”实验——PV原语实现

来源:互联网 发布:b2b行业网站源码 编辑:程序博客网 时间:2024/05/20 09:43

一、问题描述

有一个有限缓冲区和两个线程:生产者,消费者。他们分别往缓冲区写入产品和拿出产品。当缓冲区满时,生产者不能写必须等待;当缓冲区空时,消费者线程不能读,要等待。

二、实例

/*product.c*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/ipc.h>#include <semaphore.h>#include <fcntl.h>#include <pthread.h>#define FIFO "myfifo"#define N 5int lock_var;time_t end_time;char buf_r[100];sem_t mutex,full,avail;int fd;void productor(void *arg);void consumer(void *arg);int main(int argc,char *argv[]){        pthread_t id1,id2;        pthread_t mon_th_id;        int ret;        end_time = time(NULL)+30;        /*create namepipe*/        if((mkfifo(FIFO,O_CREAT|O_EXCL)<0) && (errno != EEXIST))                printf("cannot create fifoserver\n");        printf("preparing for reading bytes...");        memset(buf_r,0,sizeof(buf_r));        /*open pipe*/        fd = open(FIFO,O_RDWR | O_NONBLOCK,0);        if(fd == -1){                perror("open");                exit(1);        }        /*init sem valuable*/        ret = sem_init(&mutex,0,1);        ret = sem_init(&avail,0,N);        ret = sem_init(&full,0,0);        if(ret != 0){                perror("sem_init");        }        /*create 2 pthread*/        ret = pthread_create(&id1,NULL,(void *)productor,NULL);        if(ret != 0)                perror("pthread_cread1");        ret = pthread_create(&id2,NULL,(void *)consumer,NULL);        if(ret != 0)                perror("pthread_cread2");        pthread_join(id1,NULL);        pthread_join(id2,NULL);        exit(0);}/*product thread*/void productor(void *arg){        int i,nwrite;        while(time(NULL) < end_time){        /*p operate to the avail,mutex*/        sem_wait(&avail);        sem_wait(&mutex);        /*productor write data to the pipe*/        if((nwrite = write(fd,"hello",5)) == -1){                if(errno == EAGAIN)                        printf("the FIFO has not been read yet,please try later\n");        }        else                printf("write hello to the FIFO\n");        /*v opertate to full,mutex*/        sem_post(&full);        sem_post(&mutex);        sleep(1);        }}/*consumer thread*/void consumer(void *arg){        int nolock = 0;        int ret,nread;        while(time(NULL) < end_time){                sem_wait(&full);                sem_wait(&mutex);                memset(buf_r,0,sizeof(buf_r));                if(nread = read(fd,buf_r,100) == -1){                        if(errno = EAGAIN)                                printf("no data yet\n");                }                printf("read %s from FIFO\n",buf_r);                sem_post(&avail);                sem_post(&mutex);                sleep(1);        }}
运行结果:

[root@localhost net]# ./productpreparing for reading bytes...write hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFOwrite hello to the FIFOread hello from FIFO




原创粉丝点击