用多线程同步方法解决生产者消费者问题.docx

上传人:b****6 文档编号:8701888 上传时间:2023-02-01 格式:DOCX 页数:14 大小:41.94KB
下载 相关 举报
用多线程同步方法解决生产者消费者问题.docx_第1页
第1页 / 共14页
用多线程同步方法解决生产者消费者问题.docx_第2页
第2页 / 共14页
用多线程同步方法解决生产者消费者问题.docx_第3页
第3页 / 共14页
用多线程同步方法解决生产者消费者问题.docx_第4页
第4页 / 共14页
用多线程同步方法解决生产者消费者问题.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

用多线程同步方法解决生产者消费者问题.docx

《用多线程同步方法解决生产者消费者问题.docx》由会员分享,可在线阅读,更多相关《用多线程同步方法解决生产者消费者问题.docx(14页珍藏版)》请在冰豆网上搜索。

用多线程同步方法解决生产者消费者问题.docx

用多线程同步方法解决生产者消费者问题

武汉理工大学华夏学院

课程设计报告书

课程名称:

操作系统原理

 

题目:

用多线程同步方法解决生产者-消费者问题

系名:

信息工程系

专业班级:

姓名:

学号:

指导教师:

 

年月日

 

课程设计任务书

学生姓名:

专业班级:

指导教师:

工作单位:

设计题目:

用多线程同步方法解决生产者-消费者问题

初始条件:

Linux操作系统,GCC编译环境

要求完成的主要任务:

主要任务:

通过研究Linux的线程机制和信号量实现生产者消费者问题的并发控制。

有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1~20这20个整型数。

(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。

(2)生产者和消费者各有两个以上。

(3)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。

提示:

(1)有界缓冲区/连续存储区可用数组实现。

(2)编译命令可用:

     gcc-lpthread-o 目标文件名  源文件名

(3)多线程编程方法参见电子文档。

设计报告撰写格式要求:

1设计题目与要求2设计思想

3系统结构4数据结构的说明和模块的算法流程图

5使用说明书(即用户手册):

内容包含如何登录、退出、读、写等操作说明

6运行结果和结果分析(其中包括实验的检查结果、程序的运行情况)

7自我评价与总结

8附录:

程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释;时间安排

6月20日布置课程设计任务;分配题目后,查阅资料、准备程序;

6月21~6月23日上机调试程序、书写课程设计报告;

6月24日提交课程设计报告及相关文档。

指导教师签字:

2011年6月18日

系主任签字:

2011年6月19日

1.设计目的与要求

1.1设计目的

通过研究Linux的线程机制和信号量实现生产者消费者问题(Producer-ConsumerProblem)的并发控制。

1.2设计要求

1)为每个生产者/消费者产生一个线程,设计正确的同步算法

2)每个生产者/消费者对该存储区进行操作后,即时显示该存储区的全部内容、当

前指针位置和生产者/消费者线程的自定义标识符。

3)生产者和消费者各有两个以上。

4)多个生产者/消费者之间须共享对存储区进行操作的函数代码。

2.设计思想及系统平台

2.1设计思想

在本问题中,共需要一个Mutex和两个Semaphore.

其中,Mutex是用来锁定临界区的,以解决对共享数据buffer的互斥访问问题(无论是对生成者还是对消费者);

我们共需要两个Semaphore,这是因为在本问题中共有两个稀缺资源.

第一种是"非空"这种资源,是在消费者之间进行竞争的.

第二种是"非满"这种资源,是在生产者之间进行竞争的.

所以,一般来说,需要锁定临界区,就需要Mutex;有几种稀缺资源就需要几个Semaphore.

对稀缺资源的分析不能想当然.稀缺资源不一定是指被共享的资源,很多时候是指线程会被阻塞的条件(除了要进临界区被阻塞外).

在生产者消费者问题中,消费者会在缓冲区为空时被阻塞,所以"非空"是一种稀缺资源;

需要设置一个信号量consumer_semaphore,初值设为0;

生产者会在缓冲区为满时被阻塞,所以"非满"也是一种稀缺资源.

需要设置一个信号量producer_semaphore,初值设为buffer的大小MAX_BUFFER

2.2系统平台及使用语言

本课程设计在Linux操作系统下,使用C语言完成。

用到的工具主要有GCC编译器和VI编辑器。

3.详细算法描述

共享数据:

Semaphorebuffer_mutex=1;

Semaphoreproducer_semaphore=MAX_BUFFER;

Semaphoreconsumer_semaphore=0;

intbuffer[MAX_BUFFER];

Producer线程的处理函数:

while

(1){

Wait(producer_semaphore);

Wait(buffer_mutex);

Buffer[pn]=product;

pn=(pn+1)%MAX_BUFFER;

Signal(consumer_semaphore);

Signal(buffer_mutex);

Sleep();

}

 

producer线程的处理函数流程图如下:

consumer线程的处理函数:

while

(1){

Wait(consumer_semaphore);

Wait(buffer_mutex);

Consume=buffer[cn];

cn=(cn+1)%MAX_BUFFER;

Signal(producer_semaphore);

Signal(buffer_mutex);

Sleep();

}

consumer线程的处理函数流程图如下:

 

4.源程序清单(注释是后加上的)

用户名:

rj070126(IP:

192.168.2.254)

源程序名:

/home/rj070126/pc.c

目标程序名:

/home/rj070126/pc

运行结果:

/home/rj070126/output.txt

源程序清单如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineNUM_THREADS_P5/*定义数据为生产者*/

#defineNUM_THREADS_C5/*定义数据为消费者*/

#defineMAX_BUFFER20/*定义数据为缓存区*/

#defineRUN_TIME20/*定义运行时间*/

intbuffer[MAX_BUFFER];

intproduce_pointer=0,consume_pointer=0;

sem_tproducer_semaphore,consumer_semaphore,buffer_mutex;

pthread_tthreads_p[NUM_THREADS_P];/*声明生产者线程*/

pthread_tthreads_c[NUM_THREADS_C];/*声明消费者线程*/

FILE*fd;

void*producer_thread(void*tid);

void*consumer_thread(void*tid);

voidshowbuf();

voidhandler(){

inti;

for(i=0;i

pthread_cancel(threads_p[i]);

for(i=0;i

pthread_cancel(threads_c[i]);

}

intmain(){

inti;

signal(SIGALRM,handler);

fd=fopen("output.txt","w");/*打开一个文件用来保存结果*/

sem_init(&producer_semaphore,0,MAX_BUFFER);/*放一个值给信号灯*/

sem_init(&consumer_semaphore,0,0);

sem_init(&buffer_mutex,0,1);

for(i=0;i

buffer[i]=0;/*引发缓冲*/

/*创建线程*/

for(i=0;i

pthread_create(&threads_p[i],NULL,(void*)producer_thread,(void*)(i+1));

for(i=0;i

pthread_create(&threads_c[i],NULL,(void*)consumer_thread,(void*)(i+1));

alarm(RUN_TIME);

/*等待线程退出*/

for(i=0;i

pthread_join(threads_p[i],NULL);

for(i=0;i

pthread_join(threads_c[i],NULL);

/*清除信号灯*/

sem_destroy(&producer_semaphore);

sem_destroy(&consumer_semaphore);

sem_destroy(&buffer_mutex);

fclose(fd);

return0;

}

void*producer_thread(void*tid){

pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);

while

(1){

sem_wait(&producer_semaphore);

srand((int)time(NULL)*(int)tid);

sleep(rand()%2+1);/*一个或两个需要生产*/

while((produce_pointer+1)%20==consume_pointer);

sem_wait(&buffer_mutex);

buffer[produce_pointer]=rand()%20+1;

produce_pointer=(produce_pointer+1)%20;

if(produce_pointer==0){

printf("producer:

%dpointer_p:

%2dproduced:

%2d\n",(int)tid,19,buffer[19]);

fprintf(fd,"producer:

%dpointer_p:

%2dproduced:

%2d\n",(int)tid,19,buffer[19]);

}

else{

printf("producer:

%dpointer_p:

%2dproduced:

%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);

fprintf(fd,"producer:

%dpointer_p:

%2dproduced:

%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);

}

showbuf();

sem_post(&buffer_mutex);

sem_post(&consumer_semaphore);/*通知消费者缓冲区不是空的*/

srand((int)time(NULL)*(int)tid);

sleep(rand()%5+1);/*等待几秒钟,然后继续生产*/

}

return((void*)0);

}

void*consumer_thread(void*tid){

/*可以被其他线程使用*/

pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);

while

(1){

sem_wait(&consumer_semaphore);

srand((int)time(NULL)*(int)tid);

sleep(rand()%2+1);/*一个或两个来消费*/

sem_wait(&buffer_mutex);

printf("consumer:

%dpointer_c:

%2dconsumed:

%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);

fprintf(fd,"consumer:

%dpointer_c:

%2dconsumed:

%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);

buffer[consume_pointer]=0;

consume_pointer=(consume_pointer+1)%20;

showbuf();

sem_post(&buffer_mutex);

sem_post(&producer_semaphore);

srand((int)time(NULL)*(int)tid);

sleep(rand()%5+1);/*等待几秒钟,然后继续消费*/

}

return((void*)0);

}

/*查看缓冲区内容*/

voidshowbuf(){

inti;

printf("buffer:

");

fprintf(fd,"buffer:

");

for(i=0;i

printf("%2d",buffer[i]);

fprintf(fd,"%2d",buffer[i]);

}

printf("\n\n");

fprintf(fd,"\n\n");

}

5.运行结果与运行情况

程序运行结果如下:

producer:

1pointer_p:

0produced:

20

buffer:

200000000000000000000

producer:

3pointer_p:

1produced:

13

buffer:

2013000000000000000000

producer:

2pointer_p:

2produced:

6

buffer:

2013600000000000000000

producer:

4pointer_p:

3produced:

14

buffer:

20136140000000000000000

producer:

5pointer_p:

4produced:

20

buffer:

201361420000000000000000

consumer:

2pointer_c:

0consumed:

20

buffer:

01361420000000000000000

producer:

1pointer_p:

5produced:

20

buffer:

013614202000000000000000

consumer:

1pointer_c:

1consumed:

13

buffer:

00614202000000000000000

consumer:

3pointer_c:

2consumed:

6

buffer:

00014202000000000000000

consumer:

4pointer_c:

3consumed:

14

buffer:

0000202000000000000000

consumer:

5pointer_c:

4consumed:

20

buffer:

000002000000000000000

producer:

3pointer_p:

6produced:

1

buffer:

000002010000000000000

producer:

2pointer_p:

7produced:

14

buffer:

0000020114000000000000

consumer:

3pointer_c:

5consumed:

20

buffer:

000000114000000000000

producer:

4pointer_p:

8produced:

6

buffer:

000000114600000000000

consumer:

5pointer_c:

6consumed:

1

buffer:

000000014600000000000

producer:

5pointer_p:

9produced:

8

buffer:

000000014680000000000

consumer:

2pointer_c:

7consumed:

14

buffer:

00000000680000000000

consumer:

5pointer_c:

8consumed:

6

buffer:

00000000080000000000

producer:

1pointer_p:

10produced:

18

buffer:

000000000818000000000

consumer:

1pointer_c:

9consumed:

8

buffer:

000000000018000000000

producer:

2pointer_p:

11produced:

10

buffer:

0000000000181000000000

producer:

4pointer_p:

12produced:

10

buffer:

00000000001810100000000

consumer:

4pointer_c:

10consumed:

18

buffer:

0000000000010100000000

producer:

3pointer_p:

13produced:

3

buffer:

0000000000010103000000

consumer:

3pointer_c:

11consumed:

10

buffer:

000000000000103000000

consumer:

2pointer_c:

12consumed:

10

buffer:

00000000000003000000

producer:

1pointer_p:

14produced:

6

buffer:

00000000000003600000

consumer:

1pointer_c:

13consumed:

3

buffer:

00000000000000600000

producer:

2pointer_p:

15produced:

18

buffer:

000000000000006180000

consumer:

5pointer_c:

14consumed:

6

buffer:

000000000000000180000

producer:

1pointer_p:

16produced:

6

buffer:

000000000000000186000

producer:

3pointer_p:

17produced:

19

buffer:

0000000000000001861900

consumer:

1pointer_c:

15consumed:

18

buffer:

000000000000000061900

producer:

5pointer_p:

18produced:

7

buffer:

000000000000000061970

consumer:

3pointer_c:

16consumed:

6

buffer:

000000000000000001970

producer:

4pointer_p:

19produced:

14

buffer:

0000000000000000019714

consumer:

5pointer_c:

17consumed:

19

buffer:

000000000000000000714

consumer:

4pointer_c:

18consumed:

7

buffer:

000000000000000000014

producer:

1pointer_p:

0produced:

4

buffer:

400000000000000000014

consumer:

2pointer_c:

19consumed:

14

buffer:

40000000000000000000

consumer:

1pointer_c:

0consumed:

4

buffer:

00000000000000000000

producer:

2pointer_p:

1produced:

15

buffer:

015000000000000000000

producer:

3pointer_p:

2produced:

13

buffer:

0151300000000000000000

producer:

2pointer_p:

3produced:

3

buffer:

0151330000000000000000

说明:

“producer:

2”是指自定义标号为2的producer,“pointer_p

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1