现在的位置: 首页 > 综合 > 正文

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

2013年01月21日 ⁄ 综合 ⁄ 共 2079字 ⁄ 字号 评论关闭

一、问题描述

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

二、实例

/*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 5
int 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]# ./product
preparing for reading bytes...write hello to the FIFO
read hello from FIFO
write hello to the FIFO
read hello from FIFO
write hello to the FIFO
read hello from FIFO
write hello to the FIFO
read hello from FIFO
write hello to the FIFO
read hello from FIFO
write hello to the FIFO
read hello from FIFO

抱歉!评论已关闭.