[关闭]
@Lxjeng 2016-04-20T14:56:11.000000Z 字数 4405 阅读 1769

实验一 Windows 进程管理


  • 姓名:梁晓静 学号:1405010530 班级:计5班

1、实验目的

  • (1)学会使用 VC编写基本的Win32ConsolApplication(控制台应用程序)。
  • (2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。
  • (3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。

2、实验内容

  • (1)编写基本的 Win32 Consol Application
  • (2) 创建进程
  • (3) 父子进程的简单通信及终止进程

3、实验步骤

(1) 编写基本的 Win32 Consol Application

  • 步骤 1:登录进入Windows系统,启动CodeBlocks。
  • 步骤 2:点击 create a new project,点击Console application,选择c++,点击next,在Project title输入Project title,点击next,finish。
  • 步骤 3:将清单 1-1 所示的程序清单复制到新创建的 C/C++源程序中。编译成可执行文件。
  • 步骤 4:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的debug子目录,执行编译好的可执行程序,列出运行结果。
    此处输入图片的描述

(2) 创建进程

本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程ID和它在进程列表中的位置。

  • 步骤 1:与(1)一样,拷贝清单 1-2 中的程序,编译成可执行文件。
    在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下
    ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。
    此处输入图片的描述
    此处输入图片的描述
  • 步骤 2:修改清单1-2中的程序,将nClone的定义和初始化方法按程序注释中的修改方法进行修改,编译成可执行文件(执行前请先保存已经完成的工作)。再按步骤 2 中的方式运行,看看结果会有什么不一样。列出运行结果。从中你可以得出什么结论?说明nClone的作用。变量的定义和初始化方法(位置)对程序的执行结果有影响吗?为什么?
    此处输入图片的描述
    加参数后运行结果:
    此处输入图片的描述
    此处输入图片的描述
  • 结果:第一次修改后,程序运行结果不变。第二次修改即将nClone=0;放到if语句后面,程序会不停地创建子进程,无法停止执行,不断有执行窗口弹出,且进程ID均为0。
    nClone的作用:控制程序的起始输入值,控制窗口个数,当nClone>5时,程序就会停止执行。当nClone分别等于1,2,3,4,5时(在“命令提示符”窗口加入参数),子进程创建个数为4,3,2,1,0。

(3) 父子进程的简单通信及终止进程

  • 步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-3 中的程序,编译成 可执行文件。
  • 步骤 2:在codeblocks或在“命令提示符”窗口运行步骤1中生成的可执行文件,列出运行结果。
    此处输入图片的描述
  • 步骤 3:按源程序中注释中的提示,修改源程序1-3,编译执行(执行前请先保存已经完成的工作),列出运行结果。在程序中加入跟踪语句,或调试运行程序,同时参考MSDN中的帮助文件CreateProcess()的使用方法,理解父子进程如何传递参数。给出程序执行过程的大概描述:
    程序通过main()来传递参数,当argc的值大于1时,程序继续执行,当argc的值小于1时,程序结束执行。
  • 步骤 4:按源程序中注释中的提示,修改源程序1-3,编译执行,列出运行 结果。
  • 步骤 5:参考 MSDN中的帮助文件CreateMutex()、OpenMutex()、ReleaseMutex() 和WaitForSingleObject()的使用方法,理解父子进程如何利用互斥体进行同步的。给出父子进程同步过程的一个大概描述:
    CreateMutex()创建互斥体进程,OpenMutex()打开互斥体进程,ReleaseMutex()释放互斥体,WaitForSingleObject()检测hHandle事件的信号状态,通过这些方法可实现当前只有一个进程被创建或使用,实现进程的同步。
    结果:两次修改后,运行结果不变。

4、实验体会

  • 通过对Windows进程管理的实验,熟悉了操作系统的进程概念,理解Windows进程的“一生”。对程序清单大致阅读,虽然有很多地方不懂,但了解了主要方法及运行原理。一开始对于nClone的修改产生疑惑,但问了同学修改后就知道修改的目的了。在父子进程的简单通信及终止进程实验中,出现执行窗口无限弹出现象,但在Startclone函数前加getchar();阻止了其对内存的耗尽而死机的情况。

实验三 银行家算法的模拟与实现

1、实验目的

  • (1) 进一步了解进程的并发执行。
  • (2) 加强对进程死锁的理解。
  • (3) 掌握使用银行家算法避免死锁问题。

2、实验内容

  • 本实验的内容是要通过编写和调试一个模拟系统动态分配资源的银行家算法程序,有效地防止和避免死锁发生。具体要求如下:
    (1) 初始化时让系统拥有一定的资源;
    (2) 用键盘输入的方式允许进程动态申请资源;
    (3) 如果预分配后,系统处于安全状态,则修改系统的资源分配情况,正式分配资源;
    (4) 如果预分配后,系统处于不安全状态,则提示不能满足请求,恢复原状态。
    银行家算法. 顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行加资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不当,就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的资源需求总量不能超过系统拥有的资源总数, 使用银行算法进行资源分配可以避免死锁。

3、银行家算法中的数据结构与流程图

  1. #define MAXPROCESS 50 /*最大进程数*/
  2. #define MAXRESOURCE 100 /*最大资源数*/
  3. int AVAILABLE[MAXRESOURCE]; /*可用资源数组*/
  4. int MAX[MAXPROCESS][MAXRESOURCE]; /*最大需求矩阵*/
  5. int ALLOCATION[MAXPROCESS][MAXRESOURCE]; /*分配矩阵*/
  6. int NEED[MAXPROCESS][MAXRESOURCE]; /*需求矩阵*/
  7. int REQUEST[MAXPROCESS][MAXRESOURCE]; /*进程需要资源数*/
  8. bool FINISH[MAXPROCESS]; /*系统是否有足够的资源分配*/
  9. int p[MAXPROCESS]; /*记录序列*/
  10. int m,n; /*m个进程,n个资源*/

4、 银行家算法编程实现

(1)银行家算法

  1. void Bank() /*银行家算法*/
  2. {
  3. int i,cusneed;
  4. char again;
  5. while(1)
  6. {
  7. cout<<"请输入要申请资源的进程号(注:第1个进程号为0,依次类推)"<<endl;
  8. cin>>cusneed;
  9. cout<<"请输入进程所请求的各资源的数量"<<endl;
  10. for(i=0; i<n; i++)
  11. {
  12. cin>>REQUEST[cusneed][i];
  13. }
  14. for(i=0; i<n; i++)
  15. {
  16. if(REQUEST[cusneed][i]>NEED[cusneed][i])
  17. {
  18. cout<<"您输入的请求数超过进程的需求量!请重新输入!"<<endl;
  19. continue;
  20. }
  21. if(REQUEST[cusneed][i]>AVAILABLE[i])
  22. {
  23. cout<<"您输入的请求数超过系统有的资源数!请重新输入!"<<endl;
  24. continue;
  25. }
  26. }
  27. for(i=0; i<n; i++)
  28. {
  29. AVAILABLE[i]-=REQUEST[cusneed][i];
  30. ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
  31. NEED[cusneed][i]-=REQUEST[cusneed][i];
  32. }
  33. if(Safe())
  34. {
  35. cout<<"同意分配请求!"<<endl;
  36. }
  37. else
  38. {
  39. cout<<"您的请求被拒绝!"<<endl;
  40. for(i=0; i<n; i++)
  41. {
  42. AVAILABLE[i]+=REQUEST[cusneed][i];
  43. ALLOCATION[cusneed][i]-=REQUEST[cusneed][i];
  44. NEED[cusneed][i]+=REQUEST[cusneed][i];
  45. }
  46. }
  47. for(i=0; i<m; i++)
  48. {
  49. FINISH[i]=false;
  50. }
  51. cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
  52. cin>>again;
  53. if(again=='y'||again=='Y')
  54. {
  55. continue;
  56. }
  57. break;
  58. }
  59. }

(2)检查算法

  1. bool Safe() /*安全性算法*/
  2. {
  3. int i,j,k,l=0;
  4. int Work[MAXRESOURCE]; /*工作数组*/
  5. for(i=0; i<n; i++)
  6. Work[i]=AVAILABLE[i];
  7. for(i=0; i<m; i++)
  8. {
  9. FINISH[i]=false;
  10. }
  11. for(i=0; i<m; i++)
  12. {
  13. if(FINISH[i]==true)
  14. {
  15. continue;
  16. }
  17. else
  18. {
  19. for(j=0; j<n; j++)
  20. {
  21. if(NEED[i][j]>Work[j])
  22. {
  23. break;
  24. }
  25. }
  26. if(j==n)
  27. {
  28. FINISH[i]=true;
  29. for(k=0; k<n; k++)
  30. {
  31. Work[k]+=ALLOCATION[i][k];
  32. }
  33. p[l++]=i;
  34. i=-1;
  35. }
  36. else
  37. {
  38. continue;
  39. }
  40. }
  41. if(l==m)
  42. {
  43. cout<<"系统是安全的"<<endl;
  44. cout<<"安全序列:"<<endl;
  45. for(i=0; i<l; i++)
  46. {
  47. cout<<p[i];
  48. if(i!=l-1)
  49. {
  50. cout<<"-->";
  51. }
  52. }
  53. cout<<""<<endl;
  54. return true;
  55. }
  56. }
  57. cout<<"系统是不安全的"<<endl;
  58. return false;
  59. }

5、 实验结果与分析

此处输入图片的描述
此处输入图片的描述

6、实验总结

  • 通过银行家算法的模拟和实现,首先应弄清楚原理,然后最关键的是编程实现。整个程序的函数为void Init();bool Safe();void Bank();再分别编写即可。首先初始化,然后申请资源分配,此间通过safe函数判断是否安全,然后分配资源,改变相应数组。其中最关键的是安全性检查,只有系统安全才能避免死锁。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注