操作系统实验报告

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

//总的线程数
const
unsigned
short
THREADS_COUNT
=
Fra Baidu bibliotek
PRODUCERS_COUNT+CONSUMERS_COUNT;
HANDLE hThreads[PRODUCERS_COUNT]; //各线程的 handle DWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符 DWORD consumerID[THREADS_COUNT]; //消费者线程的标识符
}
return 0; }
//生产一个产品。简单模拟了一下,仅输出新产品的 ID 号 void Produce() {
std::cerr << "Producing " << ++ProductID << " ... "; std::cerr << "Succeed" << std::endl; }
//把新生产的产品放入缓冲区 void Append() {
} return 0; }
7
数学与信息技术学院 8
std::cout << i <<": " << g_buffer[i]; if (i==in) std::cout << " <-- 生产"; if (i==out) std::cout << " <-- 消费"; std::cout << std::endl; } }
//从缓冲区中取出一个产品 void Take() {
//控制程序结束
HANDLE g_hMutex;
//用于线程间的互斥
HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待
HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待
DWORD WINAPI Producer(LPVOID); //生产者线程 DWORD WINAPI Consumer(LPVOID); //消费者线程
4
数学与信息技术学院
unsigned short in = 0; unsigned short out = 0;
//产品进缓冲区时的缓冲区下标 //产品出缓冲区时的缓冲区下标
int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
bool g_continue = true;
std::cerr << "Appending a product ... "; g_buffer[in] = ProductID; in = (in+1)%SIZE_OF_BUFFER; std::cerr << "Succeed" << std::endl;
//输出缓冲区当前的状态 for (int i=0;i<SIZE_OF_BUFFER;++i){
这段代码将缓冲区建立成一个循环队列,使用 pv 原语进行线程间的互斥,当缓
冲区满的时候迫使生产者等待,当缓冲区空时迫使消费者等待。
//创建生产者线程
for (int i=0;i<PRODUCERS_COUNT;++i){
hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
四、实验心得
1、实验结果。截图。
3
数学与信息技术学院
2、错误与改正; 3、心得体会;
在此次实验中通过本次课程设,使我对线程(进程)之间的同步和互 斥有了非常直观的理解,学会了通过信号量去解决类似的互斥和同步问 题,提高了我的编程解决问题的能力,在代码设计阶段我学到了很多控制 线程的技巧,以及线程之间的简单通信。总之学无止境,这只是个开端, 等待自己去发掘和学习的还有更多。。。。。。。。
3、算法实现 4、需要解决的问题:
2
数学与信息技术学院
使用 pv 操作原语一组生产者向一组消费者提供消息,它们共享一个有缓
冲池,生产者向其中投放消息,消费者从中取得消息。假定这些生产者
和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只
要缓冲池未空,消费者可从缓冲池取走一个消息
4.关键代码分析:
此次实验完成了用过使用信号量去解决了消费者与生产者之间的同 步与互斥问题。
值得注意的是在创立信号量的时候,要注意创立几个信号量能解决问 题,最重要的是,在解决同步和互斥的问题中,要注意哪边是同步,哪边 是互斥,不能颠倒顺序。
附录:·主要代码· #include <windows.h> #include <iostream> const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度 unsigned short ProductID = 0; //产品号 unsigned short ConsumeID = 0; //将被消耗的产品号
} return 0; }
//消费者 DWORD WINAPI Consumer(LPVOID lpPara) {
while(g_continue){ WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Take(); Consume(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL);
for (int i=0;i<SIZE_OF_BUFFER;++i){ std::cout << i <<": " << g_buffer[i]; if (i==in) std::cout << " <-- 生产"; if (i==out) std::cout << " <-- 消费"; std::cout << std::endl;
hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consume rID[i]);
if (hThreads[i]==NULL) return -1;
5
数学与信息技术学院
}
while(g_continue){ if(getchar()){ //按回车后终止程序运行 g_continue = false; }
int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
bool g_continue = true;
//控制程序结束
HANDLE g_hMutex;
//用于线程间的互斥
HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待
HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待
三、实验过程
1、实验具体题目,分析题目: 生产者——消费者问题 1. 生产者功能描述 在同一个进程地址空间内执行的两个线程。生产
者线程生产物品 然后将物品放置在一个空缓冲区中供消费者线程消 费。当生产者线程生产物品时 如果没有空缓冲区可用 那么生产者线 程必须等待消费者线程释放出一个空缓冲区。 2.消费者功能描述 消费者线程从缓冲区中获得物品 然后释放缓冲 区。当消费者线程消费物品时 如果没有满的缓冲区 那么消费者线程 将被阻塞 直到新的物品被生产出来 2、算法流程: ① 由用户指定要产生的进程及其类别,存入进入就绪队列。 ② 调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源不存 在则进入响应的等待队列,调度程序调度就绪队列中的下一个进程。 进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就 绪队列。重复这一过程直至就绪队列为空。 ③ 程序询问是否要继续?如果要转直①开始执行,否则退出程序。
使用高级编程语言现“生产者——消费者”进程同步问题。
2.实验目标
(1)对课本知识加以巩固,在实践中提高动手能力; (2)完整的完成此次实验,并有所创新与突破; (3)独立思考,充分利用网络资源与图书资源; (4)取得一个被老师认可的高分评价;
二、实验工具
1.操作系统:windows2003 server enterprise 2.开发环境:Visual Studio 2010
while(g_continue){ if(getchar()){ //按回车后终止程序运行 g_continue = false; }
} 使用一个循环语句创建一个生产者线程,用一个函数将当前的值赋给 hThreads[i]数组来判断 此时的缓冲区是空还是满,如果是空的,则返回值为-1,然后不断重复。 创建消费者是同理。
while(g_continue){ WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Produce(); Append(); Sleep(1500); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
数学与信息技术学院
南京晓庄学院
《操作系统》实验报告
指导老师: 李青 专业班级: 软件工程(2) 学号 : 11202837 姓名 : 王益娟 完成日期: 2012 年 10 月 26 日
1
数学与信息技术学院
数学与信息技术学院
一、实验概述
1.实验目的
深入了解掌握进程的同步、互斥机制,认识理解其调度过程,并用于解决 实际生产者/消费者问题。
} }
//消耗一个产品 void Consume() {
std::cerr << "Consuming " << ConsumeID << " ... "; std::cerr << "Succeed" << std::endl; }
//生产者 DWORD WINAPI Producer(LPVOID lpPara) {
int main()
{
//创建各个互斥信号
g_hMutex = CreateMutex(NULL,FALSE,NULL);
g_hFullSemaphore
=
CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);
g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);
//创建生产者线程 for (int i=0;i<PRODUCERS_COUNT;++i){
hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if (hThreads[i]==NULL) return -1; } //创建消费者线程 for ( i=0;i<CONSUMERS_COUNT;++i){
std::cerr << "Taking a product ... "; ConsumeID = g_buffer[out]; out = (out+1)%SIZE_OF_BUFFER; std::cerr << "Succeed" << std::endl;
//输出缓冲区当前的状态
6
数学与信息技术学院
if (hThreads[i]==NULL) return -1;
}
//创建消费者线程
for ( i=0;i<CONSUMERS_COUNT;++i){
hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&con sumerID[i]); if (hThreads[i]==NULL) return -1; }
//调整下面的数值,可以发现,当生产者个数多于消费者个数时, //生产速度快,生产者经常等待消费者;反之,消费者经常等待 const unsigned short PRODUCERS_COUNT = 3; //生产者的个数 const unsigned short CONSUMERS_COUNT = 1; //消费者的个数
相关文档
最新文档