生产者和消费者问题实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#define INTE_PER_SEC 1000
#define MAX_THREAD_NUM 64
struct ThreadInfo
{
int serial;
char entity;
double delay;
int thread_request[MAX_THREAD_NUM];
int n_request;
格式: HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); d.CreateMutex 的用法 功能:本 API 产生一个命名的或者匿名的互斥量对象。 格式: HANDLE CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针 BOOLbInitialOwner, // 初始化互斥对象的所有者 LPCTSTRlpName // 指向互斥对象名的指针 ); e.CreateSemaphore 的用法 功能:本 API 创建一个命名的或者匿名的信号量对象。 格式: HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTESlpSemaphoreAttributes, // SD LONGlInitialCount, // initial count LONGlMaximumCount, // maximum count LPCTSTRlpName // object name ); f.WaitForSingleObject 的用法 功能:本 API 使程序处于等待状态,直到信号 hHandle 出现或者超出规定的 等待最长时间,信号量出现指信号量大于或等于 1。 格式:DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); g.InitializeCriticalSection 的用法
bool IfInOtherRequest(int);
int FindProducePositon();
int FindBufferPosition(int);
int main(void)
{
DWORD wait_for_all;
ifstream inFile;
for(int i=0;i< MAX_BUFFER_NUM;i++)
printf(" %d ", Thread_Info[j].thread_request[k]); cout<<endl; } printf("\n\n");
empty_semaphore=CreateSemaphore
(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical, "semaphore_for_empty");
实验报告
课程名称:
操作系统
实验名称: 生产者和消费者问题
学 号:
学生姓名:
班 级:
指导教师:
评 分:
实验日期:2012 年 10 月 22 日
1、实验目的:
掌握基本的同步互斥算法,理解生产者和消费者模型。 了解 windows 2000/XP 中多线程的并发执行机制,线程间的同步和互斥。 学习使用 windows 2000/XP 中基本的同步对象,掌握相应的 API。
3、实验环境
硬件: CPU :AMD QL64 内存: 2GB 显卡:ATI 4570 硬盘:日立 250G 软件:Windows 2000/XP。 开发工具:VC++6.0。
4、实验内容
1)实现原理 a.生产者和消费者模型 b.同步对象 c.CreateThread 的用法 功能:本 API 创建一个在调用进程的地址空间中执行的线程。
Buffer_Critical[i] = -1;
for(int j=0;j<MAX_THREAD_NUM;j++){
for(int k=0;k<MAX_THREAD_NUM;k++)
Thread_Info[j].thread_request[k] = -1;
Thread_Info[j].n_request = 0;
char c;
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++){ int Temp_serial = Thread_Info[j].serial; char Temp_entity = Thread_Info[j].entity; double Temp_delay = Thread_Info[j].delay; printf(" \n thread%2d %c %f ",Temp_serial,Temp_entity,Temp_delay); int Temp_request = Thread_Info[j].n_request; for(int k=0;k<Temp_request;k++)
h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update"); for(j=0;j<(int)n_Thread;j++){ std::string lp ="semaphore_for_produce_"; int temp =j; while(temp){ char c = (char)(temp%10); lp+=c; temp/=10; } h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp.c_str()); }
3)学会用 vc++6.0 编写使用系统 c 语言程序,基本功不扎实,程序输入不 够细心。
附录:源代码
#include<windows.h>
#include<fstream.h>
#include<stdio.h>
#include<string>
#include<conio.h>
#define MAX_BUFFER_NUM 10
}
for(i =0;i< MAX_BUFFER_NUM;i++)
InitializeCriticalSection(&PC_Critical[i]);
inFile.open("test.txt");
inFile >> n_Buffer_or_Critical;
inFile.get();
printf("输入文件是:\n");
3)数据结构 (1)用一个整型数组 Buffer_Critical 来代表缓冲区。不管是生产产品还是对
已有产品的消费都需要访问该组缓冲区。 (2)在程序中用一个自定义结构 Threadlnfo 记录一条线程的信息,即将测试
用例文件中的一行信息记录下来,用于程序创建相应的生产者或者消费者。由于 要创建多个线程,所以程序中使用了一个 Threadlnfo 结构的数组 Thread lnfo。
};
CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];
int
Buffer_Critical[MAX_BUFFER_NUM];
HANDLE h_Thread[MAX_THREAD_NUM];
ThreadInfo Thread_Info[MAX_THREAD_NUM];
2、实验要求
(1)创建生产和消费线程 在 windows2000 环境下,创建一个控制台程序,在此进程中创建 n 个线程 来模拟生产者或消费者。这些线程的信息由我们在本程序定义的“测试用例文件” 中予以制定。该文件的格式如下: 3 1P3 2P4 3C41 4P2 5C3124 (2)生产和消费的规则 a.共享缓冲区存在空闲空间时,生产者即可用共享缓冲区。 b.只有当所有的消费者需求都被满足以后,该产品所在的共享缓冲区才能 被释放,并作为空闲空间允许心的生产者适用。 c.每个消费者线程的各个消费需求之间存在先后顺序。 d.在每个县城发出读写操作申请、开始读写操作和结束读写操作时分别显 示一行提示信息。
HANDLE hMutex ); i. EnterCriticalSection 的用法: 功能:用于等待之的呢过临界区对象的所有权。 格式: VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); j.LeaveCriticalSection 的用法 功能:释放指定临界区对象的所有权。 格式: VOID LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); 2)程序结构
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;
源自文库
功能: 该函数初始化临界区对象。 格式: VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection ); h.ReleaseMutex 的用法 功能:用来打开互斥锁,即将互斥量加 1,。成功调用则返回 0。 格式:BOOL ReleaseMutex (
6、实验心得体会
1)在添加 test.txt 文件时,需在 R-WP1 及 debug 文件夹下分别储存才能实 现程序正常运行。
2)使用 vc++6.0 创建工程,应当针对程序选择相应的工程类型,例如基于 MFC 的: MFC AppWizard(exe),或者基于控制台的:Win32 Console Application, 这两种是编写普通程序时最常用。
(3)在实现本程序的消费生产模型时,具体地通过如下同步对象实现互斥: 一个互斥量 h_mutex,以实现生产者在查询和保留缓冲区内的下一个空位置时进 行互斥。每一个生产者用一个信号量与其消费者同步,通过设置 h _Semaphore[MAXTHREAD_NUM]信号量数组实现,该组信号量用于表示相应产 品已生产。同时用一个表示空缓冲区数目的信号量 empty semaphore 进行类似的 同步,指示缓冲区中是否存在空位置,以便开始生产下一个产品。每一个缓冲区 用一个同步对象实现该缓冲区上消费者之间的互斥,这通过设置临界区对象数组 PC_Critical[MAX_BUFFER_NUM]实现。
(3)打开工程目录下的 debug,再打开 test.txt,输入实验数据,并保存。
(4)最后在进行编译连接。并把实验结果截图保存。
5、实验测试及分析:
结果分析: 1、在每个程序中坐须先做 P(mutex),后做 V(mutex),二者要成对出现。夹在 二者中间的代码段就是该进程的临界区。 2、对同步信号量 full 和 empty 的 P,V 操作同样必须成对出现,但它们分别 位于不同的程序中。 3、无论在生产者进程中还是在消费者进程中,两个 P 操作的次序不能颠倒: 应先执行同 步信号量的 P 操作,然后执行互斥信号量的 P 操作。否则可能造成 进程死锁。
4)实现步骤 (1)打开 VC,选择菜单项文件->新建,选择工程选项卡并建立一个名为 R-WP1 的 Win32 console Application 工程。 (2)在工程中创建源文件 R-WP1.ccp:选择菜单项文件->新建,选择文件选 项卡并建立一个名为 R-WP1.cpp 的 C++ Source Files 文件,进行编译间接,得到 R-WP1.exe 程序。
HANDLE empty_semaphore;
HANDLE h_mutex;
DWORD n_Thread = 0;
DWORD n_Buffer_or_Critical;
HANDLE h_Semaphore[MAX_THREAD_NUM];
void Produce(void *p);
void Consume(void *p);
相关文档
最新文档