操作系统课设报告.docx

上传人:b****5 文档编号:6899393 上传时间:2023-01-12 格式:DOCX 页数:14 大小:243.40KB
下载 相关 举报
操作系统课设报告.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

操作系统课设报告

 

操作系统课程设计报告

 

题目:

生产者-消费者问题

专业:

网络工程

班级:

网络111

学号:

201110314003

姓名:

吴超

 

上海海事大学信息工程学院

2013年12月15日

 

目录

1.课程设计任务描述与要求1

2.系统总体结构描述和主要数据结构说明1

3.课程设计报告内容3

4.总结20

附录:

程序使用说明21

 

1.课程设计任务描述与要求

1.1任务描述

程序首先读入data文件,根据文件内容建立相应数量的线程,类型为P的线程为生产者,类型为C的线程为消费者;建立一个链表,作为缓冲区,用来存放生产者生产的产品,每个产品占用一个链表结点,消费者从该链表中读取产品信息。

1.2任务要求

每个线程根据文件中定义的等待时间,调用Sleep()函数休眠,然后根据“生产或消费产品的数量”字段生产或消费产品;若链表中无产品可以消费,那么消费者需要等待。

每次放入或消费产品成功后,向result结果文件中写入一行记录,记录格式如下:

线程编号、类型、本次生产或消费产品的数量。

生产者和消费者信息存放在data文件中,格式如下:

1

P

3

3

2

C

5

2

3

P

8

1

4

P

7

2

5

C

8

2

6

C

9

3

各数据的含义如下:

线程编号

类型

等待时间(秒)

生产或消费产品的数量

1

P(生产者)

3

3

2

C(消费者)

5

2

3

P(生产者)

8

1

4

P(生产者)

7

3

5

C(消费者)

8

2

6

C(消费者)

12

3

2.系统总体结构描述和主要数据结构说明

2.1系统总体结构描述

设计了两个主要函数:

生产者函数、消费者函数;

设计了三个信号量:

full信号量,判断缓冲区是否有值,初值为0;

empty信号量,判断缓冲区是否有空缓冲区,初值为缓冲区数;

mutex信号量作为互斥信号量,用于互斥的访问缓冲区。

生产者函数通过执行P操作信号量empty减1,判断缓冲区是否有空。

有空则互斥的访问缓冲区并放入数据,然后释放缓冲区,执行操作,信号量full加1。

消费者函数执行P操作,信号量full减1,判断是否有数据,有则互斥的访问缓冲区并取走数据,然后释放缓冲区,执行操作,empty信号量加1。

3.课程设计报告内容

3.1模块功能

该实验主要分为三大模块:

1.主程序,创建并控制程序的流程,

其中控制线程的活动以及信号量的操作,如图3-1-1所示;

2.生产者模块:

生产者对缓冲区的操作,如图3-1-2所示;

3.消费者模块:

消费者对缓冲区的操作,如图3-1-3所示。

3.2详细流程图

图3-1-1主程序

图3-1-2生产者图3-1-3消费者

通过分析,我们已经了解到了可以采用信号量来解决n个进程的临界区问题,这n个进程共享一个信号量mutex(mutualexclusion),并初始化为1。

每个进程Pi的组织结构如下图。

由于本系统我们研究的是有限缓冲区(Bounded-Buffer)的生产者消费者问题。

而且根据初始条件可知,该缓冲区内有20个缓冲项,每个缓冲项存储一个整形数。

信号量mutex提供了对缓冲池访问的互斥要求,并初始化为1。

信号量empty和full分别用来表示空缓冲项和满缓冲项的数量。

信号量empty初始化为20,而信号量full初始化为0;

生产者进程和消费者进程的代码如图。

注意生产者和消费者之间的对称性可以这样来理解代码:

生产者为消费者生产满缓冲项,或消费者为生产者生产空缓冲项。

 

3.3程序清单和详细注释

#include

#include

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

constintArraySize=100;

constintBuffer_Number=10;

HANDLEempty,full,mutex;

char*produce[10]={"Product_1","Product_2","Product_3","Product_4","Product_5","Product_6","Product_7","Product_8","Product_9","Product_10"};

structBuffer

{

intarray[Buffer_Number];

intin,out;

}buffer;

structProcParam{

intthreadID;

chartype;

doublewait_time;

intcount;

};

//生产者线程

unsigned__stdcallProducer(void*arg)

{

ProcParam*param;//定义一个param数组,数组的每个单元存放一个对应线程的参数

param=(ProcParam*)arg;

intnextp;

intproduce_num;

intcount=param->count;

intt=param->wait_time;

printf("线程号码%d是%c,生产中...正在生产%d个\n",param->threadID,param->type,count);

while(count--)

{

Sleep(t);

produce_num=rand()%10;

printf("线程%d:

产出产品:

%s\n",param->threadID,produce[produce_num]);

WaitForSingleObject(empty,-1);

WaitForSingleObject(mutex,-1);

nextp=buffer.in;

buffer.in=(buffer.in+1)%Buffer_Number;

printf("线程%d:

正在向array[%d]丢产品:

%s\n",param->threadID,nextp,produce[produce_num]);

ofstreamoutFile;//同时将该信息写入磁盘的某txt文件中,该函数要#include

outFile.open("result.txt",ios:

:

app);//该txt文件名可自己命名,第1次open时磁盘中没有该文件,系统会创建一个空白的。

outFile<<"ThreadID="<threadID<<"类别:

"<type<<""<<"生产数量:

"<<1<<"";

outFile<

outFile.close();

buffer.array[nextp]=produce_num;

ReleaseSemaphore(mutex,1,NULL);

ReleaseSemaphore(full,1,NULL);

}

return0;

}

//消费者线程

unsigned__stdcallConsumer(void*arg)

{

ProcParam*param;

param=(ProcParam*)arg;

intnextc;

intcon_num;

intcount=param->count;

intt=param->wait_time;

while(count--)

{

printf("线程号码%d是%c:

消费中...\n",param->threadID,param->type);

WaitForSingleObject(full,-1);

WaitForSingleObject(mutex,-1);

nextc=buffer.out;

buffer.out=(buffer.out+1)%Buffer_Number;

con_num=buffer.array[nextc];

printf("线程%d:

正在消费位于编号array[%d]的产品:

%s\n",param->threadID,nextc,produce[con_num]);

ofstreamoutFile;//同时将该信息写入磁盘的某txt文件中,该函数要#include

outFile.open("result.txt",ios:

:

app);//该txt文件名可自己命名,第1次open时磁盘中没有该文件,系统会创建一个空白的。

outFile<<"ThreadID="<threadID<<"类型:

"<type<<"消费数量:

"<<1<<"";

outFile<

outFile.close();

ReleaseSemaphore(mutex,1,NULL);

ReleaseSemaphore(empty,1,NULL);

Sleep(t);

}

return0;

}

int_tmain(intargc,_TCHAR*argv[])

{

ProcParam*param=newProcParam[ArraySize];

HANDLEhThread[ArraySize];

intThreadNum[ArraySize];

unsignedintthreadID[ArraySize];

inti=0,threadnumber,totalThreads=0;

//初始化信号量

mutex=CreateSemaphore(NULL,1,1,NULL);

empty=CreateSemaphore(NULL,Buffer_Number,Buffer_Number,NULL);

full=CreateSemaphore(NULL,0,Buffer_Number,NULL);

if(!

empty||!

full||!

mutex)

{

printf("CreateSemaphoneError!

\n");

return-1;

}

//初始化缓冲区的in和out指针变量

buffer.in=0;

buffer.out=0;

//读取文件data.txt

ifstreaminFile;

inFile.open("data.txt");

while(inFile)

{

inFile>>param[i].threadID;

inFile>>param[i].type;

inFile>>param[i].wait_time;

inFile>>param[i].count;

i++;

inFile.get();

}

threadnumber=0;

totalThreads=0;

intw=i;

for(i=0;i

if(param[i].type=='P')

{

totalThreads++;

ThreadNum[threadnumber]=i+1;

hThread[threadnumber]=(HANDLE)_beginthreadex(NULL,0,Producer,(void*)¶m[threadnumber],0,&threadID[i]);

threadnumber++;

}

else

{

totalThreads++;

ThreadNum[threadnumber]=i+1;

hThread[threadnumber]=(HANDLE)_beginthreadex(NULL,0,Consumer,(void*)¶m[threadnumber],0,&threadID[i]);

threadnumber++;

}

}

//等待所有的生产者和消费者执行完毕

WaitForMultipleObjects(totalThreads,hThread,true,INFINITE);

//关闭所有打开的句柄

for(i=0;i

CloseHandle(mutex);

CloseHandle(empty);

CloseHandle(full);

printf("程序即将结束。

\n");

getchar();

return0;

}

3.4程序执行结果截图

3.4.1生产者消费者截图

图3-4-1创建线程截图

3.4.2自动生成记录截图

图3-4-2自动生成记录截图

 

4.总结

本次的实验是在刚刚接触到操作系统这门课之后,伴随着操作系统这门课的学习,对于这门课的认识也更加深刻,包括此次做的实验内容,生产者消费者问题也有了一定的认识。

生产者进程和消费真进程共享一个有若干数据位置的缓冲区,缓冲区中有n个存放数据的位置,生产者生产产品放入缓冲区,而消费从缓冲中取产品消费,只要缓冲未满,生产者就可以将生产的产品放入缓冲,这种同步规则同时也就表明,如果缓冲区产品满,没有空的位置,则生产者就只能等待消费者取走产品,如果缓冲中没有产品,消费者就不能取产品消费,只能等待生产者放入产品。

为解决生产者和消费者进程同步的问题,设置两个信号灯full和empty。

这里,信号灯有两个功能:

首先它是资源生产和消费的计数器,其次,它是生产者和消费者之间的同步器。

信号灯full表示缓冲中存放的产品的数量,初始值为0,每当生产者生产一个产品放入缓冲后。

就执行v(full)操作,就是加1操作,表示缓冲区中加入一个产品,每当消费者在取走产品前,执行p(full)操作,其作用是判断缓冲中是否有产品,如果有,则取走一个产品。

P操作使得产品数量减一。

另外,由于有界缓冲区是一个临界资源,必须互斥使用,因此,需要设置一个互斥灯信号mutex,其初始值为1.

本来对于这个问题不是很明白,但是经过问老师和同学的交流,终于找到了方法,用了上面的方法来解决这个问题。

感觉到自己对于这方面的知识还有所欠缺,必须认真努力的好好学习。

这次的课程设计是大学生活中相当有意义的一次。

 

参考书目:

[1]刘腾红、骆正华,计算机操作系统(北京,清华大学出版社,2008年;

[2]张坤。

姜立秋、赵慧然,操作系统实验教程(北京,清华大学出版社,2008年;

[3]汤小丹、梁红兵、哲凤屏、汤子瀛,计算机操作系统,西安电子科技大学出版社,2007年。

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

当前位置:首页 > 法律文书 > 调解书

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

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