生产者和消费者问题

时间:2026-01-20

班级 姓名: 学号: 成绩:

实验名称: 生产者和消费者问题

1.实验目的:

“生产者消费者”问题是一个著名的同时性编程问题的集合。通过编写经典的“生产者消费者”问题的实验,读者可以进一步熟悉Linux 中多线程编程,并且掌握用信号量处理线程间的同步互斥问题。

2.实验内容:

“生产者消费者”问题描述如下。

有一个有限缓冲区和两个线程:生产者和消费者。他们分别把产品放入缓冲区和从缓冲区中拿走产品。当一个生产者在缓冲区满时必须等待,当一个消费者在缓冲区空时也必须等待。它们之间的关系如下图所示:

这里要求用有名管道来模拟有限缓冲区,用信号量来解决生产者消费者问题中的同步和互斥问题。

3.实验方法:

(1)使用信号量解决

(2)思考使用条件变量解决

4.实验过程

(1)信号量的考虑

这里使用3个信号量,其中两个信号量avail和full分别用于解决生产者和消费者线程之间的同步问题,mutex是用于这两个线程之间的互斥问题。其中avail初始化为N(有界缓冲区的空单元数),mutex 初始化为1,full初始化为0。

/*product.c*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <errno.h>

#include <sys/ipc.h>

#include <semaphore.h>

#include <fcntl.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 pthread1(void *arg);

void pthread2(void *arg);

int main(int argc, char *argv[])

{

pthread_t id1,id2;

pthread_t mon_th_id;

int ret;

end_time = time(NULL)+30;

/*创建有名管道*/

if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf("cannot create fifoserver\n");

printf("Preparing for reading bytes...\n");

memset(buf_r,0,sizeof(buf_r));

/*打开管道*/

fd=open(FIFO,O_RDWR|O_NONBLOCK,0);

if(fd==-1)

{

perror("open");

exit(1);

}

/*初始化互斥信号量为1*/

ret=sem_init(&mutex,0,1);

/*初始化avail信号量为N*/

ret=sem_init(&avail,0,N);

/*初始化full信号量为0*/

ret=sem_init(&full,0,0);

if(ret!=0)

{

perror("sem_init");

}

/*创建两个线程*/

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);

}

/*生产者线程*/

void productor(void *arg)

{

int i,nwrite;

while(time(NULL) < end_time){

/*P操作信号量avail和mutex*/

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");

/*V操作信号量full和mutex*/

sem_post(&full);

sem_post(&mutex);

sleep(1);

}

}

/*消费者线程*/

void consumer(void *arg)

{

int nolock=0;

int ret,nread;

while(time(NULL) < end_time){

/*P操作信号量full和mutex*/

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);

/*V操作信号量avail和mutex*/

sem_post(&avail);

sem_post(&mutex);

sleep(1);

}

}

(2)条件变量的考虑

#include <stdio.h>

#include <pthread.h>

#define BUFFER_SIZE 4

#define OVER (-1)

struct producers//定义生产者条件变量结构

{

int buffer[BUFFER_SIZE];

pthread_mutex_t lock;

int readpos, writepos;

pthread_cond_t notempty;

pthread_cond_t notfull;

};

//初始化缓冲区

void init(struct producers *b)

{

pthread_mutex_init(&b->lock,NULL);

pthread_cond_init(&b->notempty,NULL);

pthread_cond_init(&b->notfull,NULL);

b->readpos=0;

b->writepos=0;

}

//在缓冲区存放一个整数

void put(struct producers *b, int data) {

pthread_mutex_lock(&b->lock);

//当缓冲区为满时等待

while((b->writepos+1)%BUFFER_SIZE==b->readpos) {

pthread_cond_wait(&b->notfull,&b->lock); }

b->buffer[b->writepos]=data;

b->writepos++;

if(b->writepos>=BUFFER_SIZE) b->writepos=0; //发送当前缓冲区中有数据的信号

pthread_cond_signal(&b->notempty);

pthread_mutex_unlock(&b->lock);

}

int get(struct producers *b)

{

int data;

pthread_mutex_lock(&b->lock);

while(b->writepos==b->readpos)

{

pthread_cond_wait(&b->notempty,&b->lock); }

data=b->buffer[b->readpos];

b->readpos++;

if(b->readpos>=BUFFER_SIZE) b->readpos=0; pthread_cond_signal(&b->notfull);

pthread_mutex_unlock(&b->lock);

return data;

}

struct producers buffer;

void *producer(void *data)

{

…… 此处隐藏:1828字,全部文档内容请下载后查看。喜欢就下载吧 ……

生产者和消费者问题.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:4.9 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:19元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219