操作系统实验报告
- 格式:doc
- 大小:500.50 KB
- 文档页数:17
操作系统实验报告学院:专业:年级:姓名:学号:提交日期:实验一生产者和消费者问题1、程序流程图(1)生产流程图(2)消费流程图2、源代码#include <windows.h>#include <iostream>const unsigned short SIZE_OF_BUFFER = 5; //缓冲区长度unsigned short ProductID = 0; //产品号unsigned short ConsumeID = 0; //将被消耗的产品号unsigned short in = 0; //产品进缓冲区时的缓冲区下标unsigned short out = 0; //产品出缓冲区时的缓冲区下标int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列bool g_continue = true; //控制程序结束HANDLE g_hMutex; //用于线程间的互斥HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待DWORD WINAPI Producer(LPVOID); //生产者线程DWORD WINAPI Consumer(LPVOID); //消费者线程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);const unsigned short PRODUCERS_COUNT = 3; //生产者的个数const unsigned short CONSUMERS_COUNT = 4; //消费者的个数//总的线程数const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLE hThreads[PRODUCERS_COUNT];DWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符DWORD consumerID[THREADS_COUNT]; //消费者线程的标识符//创建生产者线程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 (int j=0; j<CONSUMERS_COUNT; ++j){hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[j]);if (hThreads[j]==NULL) return -1;}while(g_continue){if(getchar()){ //按回车后终止程序运行g_continue = false;}}return 0;}//生产一个产品,输出新产品的ID号void Produce(){std::cerr << "正在生产 " << ++ProductID << " ... "; std::cerr << "成功" << std::endl;}//把新生产的产品放入缓冲区void Append(){std::cerr << "加入新产品 ... ";g_buffer[in] = ProductID;in = (in+1)%SIZE_OF_BUFFER;std::cerr << "成功" << std::endl;//输出缓冲区当前的状态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;}}//从缓冲区中取出一个产品void Take(){std::cerr << "取出产品 ... ";ConsumeID = g_buffer[out];out = (out+1)%SIZE_OF_BUFFER;std::cerr << "成功" << std::endl;//输出缓冲区当前的状态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;}}//消费一个产品void Consume(){std::cerr << "消费产品 " << ConsumeID << " ... "; std::cerr << "成功" << std::endl;}//生产者DWORD WINAPI Producer(LPVOID lpPara){while(g_continue){WaitForSingleObject(g_hFullSemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Produce();Append();Sleep(5000);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hEmptySemaphore,1,NULL);}return 0;}//消费者DWORD WINAPI Consumer(LPVOID lpPara){while(g_continue){WaitForSingleObject(g_hEmptySemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Take();Consume();Sleep(5000);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hFullSemaphore,1,NULL);}return 0;}3、实验结果4、实验心得调整生产者或消费者的个数后运行程序进行对比,当生产者个数多于消费者个数时,生产速度快,生产者经常等待消费者;反之,消费者经常等待。
实验二死锁避免(银行家算法) 1、程序流程图2、源代码#include<stdio.h>#include<string.h>#include<iostream.h>#include<stdlib.h>#include<iomanip.h>#include<conio.h>const int MAX_P=20;const int MAXA=10; //定义资源的数量const int MAXB=7;typedef struct node{int a;int b;int rea;int reb;}bank;typedef struct node1{char name[20];int a;int b;int needa;int needb;}process;bank banker;process work[MAX_P];int available;//初始化函数void initpcb(){int i;banker.a=MAXA;banker.b=MAXB;banker.rea=MAXA;banker.reb=MAXB;for(i=0;i<MAX_P;i++){ strcpy(work[i].name,""); work[i].a=0;work[i].b=0;work[i].needa=0;work[i].needb=0;}}//添加进程void createpcb(){char name[20];int flag=0;int t;int needa,needb;int i;cout<<endl;cout<<"【添加进程】"<<endl;cout<<"请输入新的进程名:";cin>>name;for(i=0;i<available;i++){if(!strcmp(work[i].name,name)){flag=1;break;}}if(flag){cout<<"错误,进程已存在"<<endl;}else{cout<<"该进程所需a类资源:";cin>>needa;cout<<"该进程所需b类资源:";cin>>needb;t=1;cout<<name;if(needa>banker.rea){cout<<"错误,所需a类资源大于银行家所剩a类资源"<<endl; t=0;}if(needb>banker.reb){cout<<"错误,所需b类资源大于银行家所剩b类资源"<<endl; t=0;}if(t){strcpy(work[available].name,name);work[available].needa=needa;work[available].needb=needb;available++;cout<<"添加进程成功"<<endl<<endl;}else{cout<<"添加进程失败"<<endl<<endl;}}}//分配资源void inputactpcb(){char name[20];int i,p;int a,b;int flag;cout<<endl<<"【分配资源】"<<endl;cout<<"请输入要分配资源的进程名:";cin>>name;p=-1;for(i=0;i<available;i++){if(!strcmp(work[i].name,name)){p=i;break;}}if(p!=-1){cout<<"该进程要分配a类资源数量:";cin>>a;cout<<"该进程要分配b类资源数量:";cin>>b;flag=1;if((a>banker.rea)||(a>work[p].needa-work[p].a)){cout<<"错误,所分配a类资源大于银行家所剩a类资源或该进程还需数量"<<endl; flag=0;}if((b>banker.reb)||(b>work[p].needb-work[p].b)){cout<<"错误,所分配b类资源大于银行家所剩b类资源或该进程还需数量"<<endl; flag=0;}if(flag){banker.rea-=a;banker.reb-=b;work[p].a+=a;work[p].b+=b;cout<<"为进程分配资源成功"<<endl<<endl;}cout<<"为进程分配资源失败"<<endl<<endl; }}else{cout<<"该进程不存在"<<endl<<endl;}}//删除进程void finished(){char name[20];int i,p;cout<<endl<<"【删除进程】"<<endl;cout<<"请输入要删除的进程名:";cin>>name;p=-1;for(i=0;i<available;i++){if(!strcmp(work[i].name,name)){p=i;break;}}if(p!=-1){banker.rea+=work[p].a;banker.reb+=work[p].b;for(i=p;i<available-1;i++){work[i]=work[i+1];}strcpy(work[available-1].name,"");work[available-1].a=0;work[available-1].b=0;work[available-1].needa=0;work[available-1].needb=0;available--;cout<<"删除进程成功"<<endl<<endl;}cout<<"删除进程失败"<<endl<<endl;}}//资源情况void inputerr(){int i;cout<<endl<<"【资源情况】"<<endl;cout<<"银行家所剩资源(剩余资源/总共资源)"<<endl;cout<<"a类:"<<banker.rea<<"/"<<banker.a;cout<<" b类:"<<banker.reb<<"/"<<banker.b;cout<<endl<<endl<<"进程占用情况(已占用资源/所需资源)"<<endl<<endl; if(available>0){for(i=0;i<available;i++){cout<<"进程名:"<<work[i].name<<endl;cout<<"a类:"<<work[i].a<<"/"<<work[i].needa;cout<<" b类:"<<work[i].b<<"/"<<work[i].needb;cout<<endl<<endl;}}else{cout<<"当前没有进程"<<endl<<endl;}}void main(){int chioce;int flag=1;initpcb();while(flag){cout<<"1.资源情况 2.添加进程 3.分配资源"<<endl;cout<<"4.删除进程 0.退出系统"<<endl;cout<<"请选择:";cin>>chioce;cout<<endl;switch(chioce){inputerr();break;case 2:createpcb();break;case 3:inputactpcb();break;case 4:finished();break;case 0:flag=0;break;default:cout<<"选择错误"<<endl<<endl; }}}3、实验结果4、实验心得银行家算法是死锁避免的主要方法,思路上有很多地方值得借鉴,从中可以学到很东西。