您好,欢迎访问三七文档
班级姓名:学号:成绩:实验名称:生产者和消费者问题1.实验目的:“生产者消费者”问题是一个著名的同时性编程问题的集合。通过编写经典的“生产者消费者”问题的实验,读者可以进一步熟悉Linux中多线程编程,并且掌握用信号量处理线程间的同步互斥问题。2.实验内容:“生产者消费者”问题描述如下。有一个有限缓冲区和两个线程:生产者和消费者。他们分别把产品放入缓冲区和从缓冲区中拿走产品。当一个生产者在缓冲区满时必须等待,当一个消费者在缓冲区空时也必须等待。它们之间的关系如下图所示:这里要求用有名管道来模拟有限缓冲区,用信号量来解决生产者消费者问题中的同步和互斥问题。3.实验方法:(1)使用信号量解决(2)思考使用条件变量解决4.实验过程(1)信号量的考虑这里使用3个信号量,其中两个信号量avail和full分别用于解决生产者和消费者线程之间的同步问题,mutex是用于这两个线程之间的互斥问题。其中avail初始化为N(有界缓冲区的空单元数),mutex初始化为1,full初始化为0。/*product.c*/#includestdio.h#includestdlib.h#includeunistd.h#includepthread.h#includeerrno.h#includesys/ipc.h#includesemaphore.h#includefcntl.h#defineFIFOmyfifo#defineN5intlock_var;time_tend_time;charbuf_r[100];sem_tmutex,full,avail;intfd;voidpthread1(void*arg);voidpthread2(void*arg);intmain(intargc,char*argv[]){pthread_tid1,id2;pthread_tmon_th_id;intret;end_time=time(NULL)+30;/*创建有名管道*/if((mkfifo(FIFO,O_CREAT|O_EXCL)0)&&(errno!=EEXIST))printf(cannotcreatefifoserver\n);printf(Preparingforreadingbytes...\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(pthreadcread1);ret=pthread_create(&id2,NULL,(void*)consumer,NULL);if(ret!=0)perror(pthreadcread2);pthread_join(id1,NULL);pthread_join(id2,NULL);exit(0);}/*生产者线程*/voidproductor(void*arg){inti,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(TheFIFOhasnotbeenreadyet.Pleasetrylater\n);}elseprintf(writehellototheFIFO\n);/*V操作信号量full和mutex*/sem_post(&full);sem_post(&mutex);sleep(1);}}/*消费者线程*/voidconsumer(void*arg){intnolock=0;intret,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(nodatayet\n);}printf(read%sfromFIFO\n,buf_r);/*V操作信号量avail和mutex*/sem_post(&avail);sem_post(&mutex);sleep(1);}}(2)条件变量的考虑#includestdio.h#includepthread.h#defineBUFFER_SIZE4#defineOVER(-1)structproducers//定义生产者条件变量结构{intbuffer[BUFFER_SIZE];pthread_mutex_tlock;intreadpos,writepos;pthread_cond_tnotempty;pthread_cond_tnotfull;};//初始化缓冲区voidinit(structproducers*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;}//在缓冲区存放一个整数voidput(structproducers*b,intdata){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);}intget(structproducers*b){intdata;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);returndata;}structproducersbuffer;void*producer(void*data){intn;for(n=0;n10;n++){printf(Producer:%d--\n,n);put(&buffer,n);}put(&buffer,OVER);returnNULL;}void*consumer(void*data){intd;while(1){d=get(&buffer);if(d==OVER)break;printf(Consumer:--%d\n,d);}returnNULL;}intmain(){pthread_ttha,thb;void*retval;init(&buffer);pthread_create(&tha,NULL,producer,0);pthread_create(&thb,NULL,consumer,0);pthread_join(tha,&retval);pthread_join(thb,&retval);return0;}
本文标题:生产者和消费者问题
链接地址:https://www.777doc.com/doc-4866366 .html