实现生产者消费者问题课程设计报告书Word文件下载.docx
《实现生产者消费者问题课程设计报告书Word文件下载.docx》由会员分享,可在线阅读,更多相关《实现生产者消费者问题课程设计报告书Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
指导教师:
军工作单位:
题目:
实现生产者消费者问题
初始条件:
学习了高级语言程序设计、汇编语言、数据结构、计算机组成原理课程,掌握了一种计算机高级语言。
要求完成的主要任务:
(包括课程设计工作量与其技术要求,以与说明书撰写等具体要求)
1.通过研究Linux的线程机制和信号量实现生产者消费者(BoundedBuffer)问题的并发控制。
2.实验条件要求:
每人一台与Linux主机联网的Windows主机,普通用户权限。
3.编程与上机实现;
4.撰写课程设计报告,包括:
1)设计题目与要求
2)总的设计思想与系统平台、语言、工具等。
3)数据结构与模块说明(功能与流程图)
4)源程序
5)运行结果与运行情况
6)调试记录
7)自我评析和总结
时间安排:
序号
阶段容
所需时间
1
消化资料、系统设计
1天
2
编程、调试
3天
3
撰写报告
合计
5天
指导教师签名:
2011年12月26日
系主任(或责任教师)签名:
年月日
1设计题目与要求
1.1设计题目
1.2设计要求
(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部容、当前指针位置和生产者/消费者线程的标识符。
(2)生产者和消费者各有两个以上。
(3)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。
2设计思想与系统平台、语言、工具
2.1设计思想
生产者—消费者问题是一种同步问题的抽象描述。
计算机系统中的每个进程都可以消费或生产某类资源。
当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
在同一时刻只能有一个生产者或一个消费者使用缓冲区,有互斥信号量可以控制各个生产者和消费者之间互斥,使得生产和消费的工作能够有序的进行,而不至于发生死锁。
通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。
假定生产者和消费者的优先级是一样的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。
类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。
应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。
在本问题中,共需要一个Mutex和两个Semaphore.其中,Mutex是用来锁定临界区的,以解决对共享数据buffer的互斥访问问题(无论是对生成者还是对消费者);
共需要两个Semaphore,这是因为在本问题中共有两个稀缺资源.第一种是"
非空"
这种资源,是在消费者之间进行竞争的.第二种是"
非满"
这种资源,是在生产者之间进行竞争的.
所以,一般来说,需要锁定临界区,就需要Mutex;
有几种稀缺资源就需要几个Semaphore.对稀缺资源的分析不能想当然.稀缺资源不一定是指被共享的资源,很多时候是指线程会被阻塞的条件(除了要进临界区被阻塞外).在生产者消费者问题中,消费者会在缓冲区为空时被阻塞,所以"
是一种稀缺资源;
需要设置一个信号量consumer_semaphore,初值设为0;
生产者会在缓冲区为满时被阻塞,所以"
也是一种稀缺资源.需要设置一个信号量producer_semaphore,初值设为buffer的大小MAX_BUFFER
2.2系统平台与语言、工具
(1)操作系统:
Linux
(2)程序设计语言:
C语言
(3)编译器:
GCC
3数据结构与模块说明
共享数据:
#defineNUM20
intqueue[NUM];
intp=0,c=0;
//记录动态数组下标位置
sem_tblank_number,product_number;
pthread_mutex_tcounter_mutex=PTHREAD_MUTEX_INITIALIZER;
生产者线程入口函数:
void*producer_thread_fun(unsignedint*arg)
{
intrealarg=(int)arg;
//强制类型转换参数
producer(realarg);
returnNULL;
}
生产者线程处理函数:
void*producer(constinti)
{while
(1)
{
sem_wait(&
blank_number);
pthread_mutex_lock(&
counter_mutex);
sleep
(2);
queue[p]=p+1;
pthread_mutex_unlock(&
sem_post(&
product_number);
sleep(rand()%5);
//Randomblock0-4seconds
}
生产者线程的函数流程图如下:
消费者线程入口函数:
void*consumer_thread_fun(void*arg)
{intrealarg=(int)arg;
consumer(realarg);
消费者线程的处理函数:
void*consumer(constinti)
sleep(rand()%5);
}
消费者线程的处理函数流程图如下:
4源程序
#include<
stdlib.h>
pthread.h>
stdio.h>
semaphore.h>
#include<
time.h>
//Recordlocationofthedynamicarraysubscript
//ProducerFunction
intj;
time_tt;
srand((unsigned)time(&
t));
//Initializetherandomnumberseed
while
(1)
{sem_wait(&
printf("
ProducerNumber%dthreadidentifier:
%u,"
i+1,((unsignedint)pthread_self()));
Produce%d\n"
queue[p]);
Thecurrentstateofthebuffe:
**********************************\n"
);
Number:
"
for(j=0;
j<
NUM;
j++)
{
printf("
%4d"
j+1);
}
\nValue:
NUM;
queue[j]);
\nPointer:
j++)
if(j!
=p)
printf("
"
else
printf("
+"
\n"
p=(p+1)%NUM;
//pbackwardone
//Productionofthethreadentryfunction
//Forcetypeconversionparameters
//Consumerfunction
ConsumerNumber%dthreadidentifier:
Consumed%d\n"
queue[c]);
queue[c]=0;
//Fillemptyposition0
Thecurrentstateofthebuffer:
Number:
}
\nPointer:
=c)
-"
c=(c+1)%NUM;
sleep(rand()%5);
//consumerthreadentryfunction
void*consumer_thread_fun(void