生产者消费者问题.docx

上传人:b****0 文档编号:1004517 上传时间:2022-10-15 格式:DOCX 页数:12 大小:19.66KB
下载 相关 举报
生产者消费者问题.docx_第1页
第1页 / 共12页
生产者消费者问题.docx_第2页
第2页 / 共12页
生产者消费者问题.docx_第3页
第3页 / 共12页
生产者消费者问题.docx_第4页
第4页 / 共12页
生产者消费者问题.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

生产者消费者问题.docx

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

生产者消费者问题.docx

生产者消费者问题

实训二操作系统中的经典线程同步问题

一、实训目的:

1、通过对“生产者-消费者”问题编程实现,了解线程创建、同步信号量、互斥信号量、临界区的创建和使用。

2、了解线程互斥和同步机制。

3、了解PV原语和信号量在线程互斥和同步机制中的运用。

二、实训环境:

一台PC机/人

三、预习内容:

1、进程的控制。

2、进程同步。

3、本实验内容主要对应于教材第2章中关于进程的各节

四、实训内容:

1、编写进程控制程序并运行,理解进程控制的各操作。

2、生产者和消费者问题,本实验用到几个API函数:

CreatThread,CreatMutex,CreatSemaphore,WaitForSingleObject,ReleaseSemaphore,ReleaseMutex,InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection

这些函数的作用:

      CreatThread:

创建一个线程,该线程在调用进程的地址空间中执    

 CreatMutex:

产生一个命名的或者匿名的互斥量对象。

WaitForSingleObject(对应p操作)锁上互斥锁,ReleaseMutex(对应v操作)打开互斥锁。

   CreateSemaphore:

创建一个命名的或者匿名的信号对象。

信号量可以看作是在互斥量上的一个扩展。

  WaitForSingleObject:

使程序处于等待状态,直到信号量(或互斥量)hHandle出现或者超过规定的等待最长时间,信号量出现指信号量大于或等于1,互斥量出现指打开互斥锁。

在返回之前将信号量减1或者锁上互斥锁。

  ReleaseSemaphore:

将所指信号量加上指定大小的一个量,执行成功,则返回非0值。

  ReleaseMutex:

用来打开互斥量,即将互斥量加1。

成功调用则返回0。

  InitializeCriticalSection:

该函数初始化临界区对象。

  EnterCriticalSection:

该函数用于等待指定临界区对象的所有权。

当调用线程被赋予所有权时,该函数返回。

       

 LeaveCriticalSection:

该函数释放指定的临界区对象的所有权。

3、测试数据设计及测试结果分析

已知测试用例文件输入的文件时:

5

thread1P5.000000

thread2P4.000000

thread3P2.000000

thread4C6.00000056

thread5P7.000000

thread6P1.000000

thread7C3.000000132

生产者6发送生产请求信号.

生产者6开始在缓冲区0生产产品.

生产者6完成生产过程:

缓冲区【0】:

6

生成者3发送生产请求信号.

生产者3开始在缓冲区1生产产品.

生产者3完成生产过程:

缓冲区【1】:

3

消费者7请求消费1产品

消费者7请求消费1产品

生产者2发送生成者请求信号.

生产者2开始在缓冲区2生产产品

生产者2完成生产过程:

缓冲区【2】:

2

生产者1发送生产请求信号.

生产者1开始在缓冲区3生产产品.

生产者1完成生产过程:

缓冲区【3】:

1

消费者7开始消费1产品

消费者7成功消费1:

缓冲区【3】:

-1

消费者7请求消费3产品

消费者7开始消费3产品

消费者7成功消费3:

缓冲区【1】:

-1

消费者7请求消费2产品

消费者7开始消费2产品

消费者7成功消费2:

缓冲区【2】:

-1

消费者4请求消费5产品

生产者5发送生产请求信号.

生产者5开始在缓冲区1生产产品

生产者5完成生产过程

缓冲区【1】:

5

消费者4请求消费5产品

消费者4请求消费5产品

缓冲区【1】:

-1

消费者4请求消费6产品

消费者4开始消费6产品

消费者4成功消费6:

缓冲区【0】:

-1

五、参考程序

#include

#include

#include

#include

#include

//定义一些常量;

//本程序允许的最大临界区数;

#defineMAX_BUFFER_NUM10

//秒到毫秒的乘法因子;

#defineINTE_PER_SEC1000

//本程序允许的生产和消费线程的总数;

#defineMAX_THREAD_NUM64

//定义一个结构,记录在测试文件中指定的每一个线程的参数

structThreadInfo

{

intserial;//线程序列号

charentity;//是P还是C

doubledelay;//线程延迟

intthread_request[MAX_THREAD_NUM];//线程请求队列

intn_request;//请求个数

};

//全局变量的定义

//临界区对象的声明,用于管理缓冲区的互斥访问;

CRITICAL_SECTIONPC_Critical[MAX_BUFFER_NUM];

intBuffer_Critical[MAX_BUFFER_NUM];//缓冲区声明,用于存放产品;

HANDLEh_Thread[MAX_THREAD_NUM];//用于存储每个线程句柄的数组;

ThreadInfoThread_Info[MAX_THREAD_NUM];//线程信息数组;

HANDLEempty_semaphore;//一个信号量;

HANDLEh_mutex;//一个互斥量;

DWORDn_Thread=0;//实际的线程的数目;

DWORDn_Buffer_or_Critical;//实际的缓冲区或者临界区的数目;

HANDLEh_Semaphore[MAX_THREAD_NUM];//生产者允许消费者开始消费的信号量;

//生产消费及辅助函数的声明

voidProduce(void*p);

voidConsume(void*p);

boolIfInOtherRequest(int);

intFindProducePositon();

intFindBufferPosition(int);

intmain(void)

{

//声明所需变量;

DWORDwait_for_all;

ifstreaminFile;

//初始化缓冲区;

for(inti=0;i

Buffer_Critical[i]=-1;

//初始化每个线程的请求队列;

for(intj=0;j

for(intk=0;k

Thread_Info[j].thread_request[k]=-1;

Thread_Info[j].n_request=0;

}

//初始化临界区;

for(i=0;i

InitializeCriticalSection(&PC_Critical[i]);

//打开输入文件,按照规定的格式提取线程等信息;

inFile.open("test1.txt");

//从文件中获得实际的缓冲区的数目;

inFile>>n_Buffer_or_Critical;

inFile.get();

printf("输入文件是:

\n");

//回显获得的缓冲区的数目信息;

printf("%d\n",(int)n_Buffer_or_Critical);

//提取每个线程的信息到相应数据结构中;

while(inFile){

inFile>>Thread_Info[n_Thread].serial;

inFile>>Thread_Info[n_Thread].entity;

inFile>>Thread_Info[n_Thread].delay;

charc;

inFile.get(c);

while(c!

='\n'&&!

inFile.eof()){

inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];

inFile.get(c);

}

n_Thread++;

}

//回显获得的线程信息,便于确认正确性;

for(j=0;j<(int)n_Thread;j++){

intTemp_serial=Thread_Info[j].serial;

charTemp_entity=Thread_Info[j].entity;

doubleTemp_delay=Thread_Info[j].delay;

printf("\nthread%2d%c%f",Temp_serial,Temp_entity,Temp_delay);

intTemp_request=Thread_Info[j].n_request;

for(intk=0;k

printf("%d",Thread_Info[j].thread_request[k]);

cout<

}

printf("\n\n");

//创建在模拟过程中几个必要的信号量

empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical,

"semaphore_for_empty");

h_mutex=CreateMutex(NULL,FALSE,"mutex_for_update");

//下面这个循环用线程的ID号来为相应生产线程的产品读写时所

//使用的同步信号量命名;

for(j=0;j<(int)n_Thread;j++){

std:

:

stringlp="semaphore_for_produce_";

inttemp=j;

while(temp){

charc=(char)(temp%10);

lp+=c;

temp/=10;

}

h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp.c_str());

}

//创建生产者和消费者线程;

for(i=0;i<(int)n_Thread;i++){

if(Thread_Info[i].entity=='P')

h_Thread[i]=CreateThre

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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