生产者和消费者问题

来源:互联网 发布:sql server时间戳转换 编辑:程序博客网 时间:2024/06/06 06:51

这是一道学习linux时候的历史遗留问题。。。

题目:用线程实现:生产者与消费者:
一个缓冲区,两个线程:生产者和消费者,一个放入缓存一个从缓存取数据,生产者在满时等待,消费者在空时等待,两者互斥执行。

实现:用一个有名管道myfifo作为缓存,因为两者互斥执行,所以myfifo属于临界资源。
而对临界资源的互斥与同步要用信号量来解决。
使用3个信号量,一个二值信号量(mutex )控制是否允许对管道操作。
一个avail 表示缓冲区中的空单元数 初始值为N
一个full信号量表示缓冲区中的非空单元数 初始值为 0
这里写图片描述

代码实现:

#include <time.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <pthread.h>#include <errno.h>#include <semaphore.h>#include <sys/ipc.h>#include <string.h>#define  FIFO "myfifo"#define BUFFER_SIZE 5#define TIME_SIZE 30int fd;time_t end_time;sem_t mutex, full, avail;char buf_r[100];void *producer(void *arg){    int i, nwrite;    while(time(NULL) < end_time)    {        sem_wait(&avail);        sem_wait(&mutex);        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");        }        sem_post(&full);        sem_post(&mutex);        sleep(1);     } }void *customer(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);    }}int main(){    pthread_t thrd_prd_id, thrd_cst_id;     pthread_t mon_th_id;    int ret;    end_time = time(NULL) + 30;    memset(buf_r, 0, sizeof(buf_r));    //创建管道     if((mkfifo(FIFO, O_CREAT| O_EXCL) < 0) && (errno != EEXIST))    {        printf("pipe create error\n");        exit(1);    }    //打开管道    fd = open(FIFO, O_RDWR| O_NONBLOCK, 0);    if(fd == -1)    {        perror("open error!\n");        exit(1);    }    //信号量 初始化     ret = sem_init(&mutex, 0, 1);    ret += sem_init(&avail, 0, BUFFER_SIZE);    ret += sem_init(&full, 0, 0);    if(ret != 0)    {        printf("Any semaphore initialization failed\n");        return ret;    }    //创建生产者线程    ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);    if(ret != 0)    {        printf("Create producer thread error\n");        return ret;     }     //创建消费者线程    ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);    if(ret != 0)    {        printf("Create producer thread error\n");        return ret;    }     pthread_join(thrd_prd_id, NULL);    pthread_join(thrd_cst_id, NULL);    close(fd);    return 0;}