操作系统实验_操作系统实验一 - CSDN
操作系统实验 订阅
《操作系统实验》是2004年中央电大出版社出版的图书,作者是孟庆昌。 展开全文
《操作系统实验》是2004年中央电大出版社出版的图书,作者是孟庆昌。
信息
页    数
93
作    者
孟庆昌
定    价
12.00元
书    名
操作系统实验
出版时间
2004-7
出版社
中央电大
副标题
操作系统实验
ISBN
9787304018801
接单内容简介
内容介绍《计算机应用专业系列教材·操作系统实验》以SCO UNIX为例介绍了操作系统的安装和使用,通过指导读者上机实验,使读者既加深对操作系统概念的理解,又学会对UNIX系统的一般使用。全书共分九章,内容包括:UNIX系统安装,SCO UNIX图形界面,用户帐户建立,vi使用,进程管理,存储器管理,文件系统,设备管理和简单shell编程。《计算机应用专业系列教材·操作系统实验》是中央电大的实验教材,同时也可作为广大UNIX初学者的指导书。 [1] 
收起全文
精华内容
参与话题
  • 1.实验一 先来先服务FCFS和短作业优先SJF进程调度算法 下载地址:http://download.csdn.net/download/xunciy/10237052 FCFS SJF 2.实验二 时间片轮转RR进程调度算法 下载地址:...

    免责申明:上传资料仅供学习交流使用,禁止一切不正当使用行为,如有事故本人概不负责
    操作系统期末知识点整理:https://download.csdn.net/download/xunciy/10527240
    1.实验一 先来先服务FCFS和短作业优先SJF进程调度算法
    下载地址:http://download.csdn.net/download/xunciy/10237052
    FCFS
    FCFS
    SJF
    SJF

    2.实验二 时间片轮转RR进程调度算法
    下载地址:http://download.csdn.net/download/xunciy/10237055
    时间片q=1
    时间片q=1
    时间片q=4
    时间片q=4

    3.实验三 预防进程死锁的银行家算法
    下载地址:http://download.csdn.net/download/xunciy/10238408
    AntiDeadlock

    4.实验四 动态分区分配算法
    下载地址:http://download.csdn.net/download/xunciy/10238411
    首次适应算法FF和环首次适应算法NF
    FF和NF
    最佳适应算法BF和最坏适应算法WF
    BF和WF

    5.实验五 虚拟内存页面置换算法
    下载地址:http://download.csdn.net/download/xunciy/10237067
    FIFO
    FIFO
    OPI和LRU
    OPI和LRU

    6.实验六 磁盘调度算法
    下载地址:http://download.csdn.net/download/xunciy/10238421
    先来先服务FCFS、最短寻道时间优先SSTF
    FCFS和SSTF
    扫描SCAN、循环扫描CSCAN
    SCAN和CSCAN

    免责申明:上传资料仅供学习交流使用,禁止一切不正当使用行为,如有事故本人概不负责

    展开全文
  • 操作系统实验及代码(全)

    万次阅读 多人点赞 2017-03-21 08:33:58
    题目1:基本操作命令实践 题目2:Windows进程的创建与销毁 题目3 作业调度 题目4 基于优先数的时间片轮转调度算法调度处理器 题目5 银行家算法 题目6 内存管理 题目7 页面置换 题目8 磁盘调度

    题目1:基本操作命令实践

    实验目的:

    配合操作系统课程的学习,加深操作系统提供命令接口的功能的理解。

    内容及要求:

    一、验证如下命令,并且将每条命令的具体格式,记录在实验报告中。最常见的操作系统管理的一些命令。其中包括:

    1、最基本、最常用的测试物理网络连通性的命令ping。ping命令用于确定本地主机是否与网络上另外一台主机相连。

    2、查看DNS、IP地址、MAC地址的命令ipconfig。

    3、网络信使命令net send。

    4、显示计算机当前所开放的所有端口的命令netstat,并了解端口的具体意义。

    5、了解net系列命令的使用。例如net view, net user,  net share等。

    6、路由跟踪命令tracert及pathping。

    7、远程桌面连接命令mstsc。

    二、借助网络,再列举一些操作系统管理命令,不少于5个并且将每条命令的具体格式,记录在实验报告中。

    1.appwiz.cpl:程序和功能

    2.calc:启动计算器

    3.certmgr.msc:证书管理实用程序

    4.charmap:启动字符映射表

    5.chkdsk.exeChkdsk磁盘检查(管理员身份运行命令提示符)

    6.cleanmgr: 打开磁盘清理工具

    7.cliconfgSQL SERVER客户端网络实用工具

    8.cmstp:连接管理器配置文件安装程序

    9.cmd.exeCMD命令提示符

    10.自动关机命令

    Shutdown -s -t 600:表示600秒后自动关机

    shutdown -a :可取消定时关机

    Shutdown -r -t 600:表示600秒后自动重启

    rundll32 user32.dll,LockWorkStation:表示锁定计算机

    11.colorcpl:颜色管理,配置显示器和打印机等中的色彩

    12.CompMgmtLauncher:计算机管理

    13.compmgmt.msc:计算机管理

    14.credwiz:备份或还原储存的用户名和密码

    15.comexp.msc:打开系统组件服务

    16.control:控制面版

    17.dcomcnfg:打开系统组件服务

    18.Dccw:显示颜色校准

    19.devmgmt.msc:设备管理器

    20.desk.cpl:屏幕分辨率

    21.dfrgui:优化驱动器 Windows7→dfrg.msc:磁盘碎片整理程序

    22.dialer:电话拨号程序

    23.diskmgmt.msc:磁盘管理

    24.dvdplayDVD播放器

    25.dxdiag:检查DirectX信息

    26.eudcedit:造字程序

    27.eventvwr:事件查看器

    28.explorer:打开资源管理器

    29.Firewall.cplWindows防火墙

    30.FXSCOVER:传真封面编辑器

    31.fsmgmt.msc:共享文件夹管理器

    32.gpedit.msc:组策略

    33.hdwwiz.cpl:设备管理器

    34.inetcpl.cplInternet属性

    35.intl.cpl:区域

    36.iexpress:木马捆绑工具,系统自带

    37.joy.cpl:游戏控制器

    38.logoff:注销命令

    39.lusrmgr.msc:本地用户和组

    40.lpksetup:语言包安装/删除向导,安装向导会提示下载语言包

    41.lusrmgr.msc:本机用户和组

    42.main.cpl:鼠标属性

    43.mmsys.cpl:声音

    44.magnify:放大镜实用程序

    45.mem.exe:显示内存使用情况(如果直接运行无效,可以先管理员身份运行命令提示符,在命令提示符里输入mem.exe>d:a.txt即可打开d盘查看a.txt,里面的就是内存使用情况了。当然什么盘什么文件名可自己决定。)

    46.MdSched:Windows内存诊断程序

    47.mmc:打开控制台

    48.mobsync:同步命令

    49.mplayer2:简易widnows mediaplayer

    50.Msconfig.exe:系统配置实用程序

    51.msdt:微软支持诊断工具

    52.msinfo32:系统信息

    53.mspaint:画图

    54.MsraWindows远程协助

    55.mstsc:远程桌面连接

    56.NAPCLCFG.MSC:客户端配置

    57.ncpa.cpl:网络连接

    58.narrator:屏幕讲述人

    59.Netplwiz:高级用户帐户控制面板,设置登陆安全相关的选项

    60.netstat : an(TC)命令检查接口

    61.notepad:打开记事本

    62.NslookupIP地址侦测器

    63.odbcad32ODBC数据源管理器

    64.OptionalFeatures:打开打开或关闭Windows功能对话框

    65.osk:打开屏幕键盘

    66.perfmon.msc:计算机性能监测器

    67.perfmon:计算机性能监测器

    68.PowerShell:提供强大远程处理能力

    69.printmanagement.msc:打印管理

    70.powercfg.cpl:电源选项

    71.psr:问题步骤记录器

    72.Rasphone:网络连接

    73.Recdisc:创建系统修复光盘

    74.Resmon:资源监视器

    75.Rstrui:系统还原

    76.regedit.exe:注册表

    77.regedt32:注册表编辑器

    78.rsop.msc:组策略结果集

    79.sdclt:备份状态与配置,就是查看系统是否已备份

    80.secpol.msc:本地安全策略

    81.services.msc:本地服务设置

    82.sfc /scannow:扫描错误并复原/windows文件保护

    83.sfc.exe:系统文件检查器

    84.shrpubw:创建共享文件夹

    85.sigverif:文件签名验证程序

    86.sluiWindows激活,查看系统激活信息

    87.slmgr.vbs -dlv :显示详细的许可证信息

    slmgr.vbs -dli :显示许可证信息

    slmgr.vbs -xpr :当前许可证截止日期

    slmgr.vbs -dti :显示安装ID以进行脱机激活

    slmgr.vbs -ipk (Product Key)安装产品密钥

    slmgr.vbs -ato :激活Windows

    slmgr.vbs -cpky :从注册表中清除产品密钥(防止泄露引起的攻击)

    slmgr.vbs -ilc (License file)安装许可证

    slmgr.vbs -upk :卸载产品密钥

    slmgr.vbs -skms (name[ort] )批量授权

    88.snippingtool:截图工具,支持无规则截图

    89.soundrecorder:录音机,没有录音时间的限制

    90.StikyNot:便笺

    91.sysdm.cpl:系统属性

    92.sysedit:系统配置编辑器

    93.syskey:系统加密,一旦加密就不能解开,保护系统的双重密码

    94.taskmgr:任务管理器(旧版)

    95.TM任务管理器(新版)

    96.taskschd.msc:任务计划程序

    97.timedate.cpl:日期和时间

    98.UserAccountControlSettings用户账户控制设置

    99.utilman:辅助工具管理器

    100.wf.msc:高级安全Windows防火墙

    101.WFSWindows传真和扫描

    102.wiaacmgr:扫描仪和照相机向导

    103.winver:关于Windows

    104.wmimgmt.msc:打开windows管理体系结构(WMI)

    105.write:写字板

    106.wscui.cpl:操作中心

    107.wscriptwindows脚本宿主设置

    108.wuappWindows更新

     


     

    题目2:Windows进程的创建与销毁


    内容及要求:

    ① 掌握Windows进程的创建和销毁API的调用方法;编程代码,在程序中创建和销毁一个Word进程;

    ② 能够挂起和激活被创建进程的主线程;

    ③ 通过Windows进程管理器查看系统进程列表的变化。

    实验指导:

    ①创建进程的API

    BOOL CreateProcess(

     LPCTSTR lpApplicationName,

     LPTSTR lpCommandLine,

     LPSECURITY_ATTRIBUTES lpProcessAttributes,

     LPSECURITY_ATTRIBUTES lpThreadAttributes,

     BOOL bInheritHandles,

     DWORD dwCreationFlags,

     LPVOID lpEnvironment,

     LPCTSTR lpCurrentDirectory,

     LPSTARTUPINFO lpStartupInfo,

     LPPROCESS_INFORMATION lpProcessInformation

    );

    例程:

    void main( VOID ){
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );
        // Start the child process. 
        if( !CreateProcess( NULL, // No module name (use command line). 
            "MyChildProcess", // Command line. 
            NULL,             // Process handle not inheritable. 
            NULL,             // Thread handle not inheritable. 
            FALSE,            // Set handle inheritance to FALSE. 
            0,                // No creation flags. 
            NULL,             // Use parent's environment block. 
            NULL,             // Use parent's starting directory. 
            &si,              // Pointer to STARTUPINFO structure.
            &pi )             // Pointer to PROCESS_INFORMATION structure.
        ) {
            ErrorExit( "CreateProcess failed." );
        }
        // Wait until child process exits.
        WaitForSingleObject( pi.hProcess, INFINITE );
        // Close process and thread handles. 
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }

    销毁进程API

    BOOL TerminateProcess(

     HANDLE hProcess,

     UINT uExitCode

    );

    ③挂起进程的主线程API

    DWORD SuspendThread(

     HANDLE hThread

    );

    ④激活进程的主线程API

    DWORD ResumeThread(

     HANDLE hThread

    );

    ⑤进程查看器


    #include"iostream"
    #include"windows.h"
    using namespacestd;
    void  main( VOID ){
                                               STARTUPINFOsi;
                                     PROCESS_INFORMATIONpi;
                        TCHARszCommandLine[]=TEXT("NOTEPAD");
                                      ZeroMemory(&si, sizeof(si) );
                                                si.cb= sizeof(si);
                                      ZeroMemory(&pi, sizeof(pi) );
     
    if(!CreateProcess( NULL, szCommandLine, NULL,NULL, FALSE,0,NULL, NULL,&si,&pi ) )
     
    {
                                fprintf(stderr,"Createprocess Failed ");
     
    }
     
    int x;
    while(true){
    cout<<"请输入要选择的操作:\n0:销毁进程\n1:挂起进程\n2:激活进程\n3:退出\n";
                                                       cin>>x;
                                                    switch(x){
                                                       case0:
                                                                  if(TerminateProcess(pi.hProcess,0))
                                                                                                                           cout<<"销毁进程成功"<<endl;
                                                                                                               else
                                                                                                                           cout<<"销毁失败"<<endl;
                                                                                                           break;
                                                       case1:
                                                                       if(SuspendThread(pi.hThread))
                                                                                                                           cout<<"挂起进程成功"<<endl;
                                                                                                               else
                                                                                                                           cout<<"挂起失败"<<endl;
                                                                                                           break;
                                                       case2:
                                                                        if(ResumeThread(pi.hThread))
                                                                                                                           cout<<"激活进程成功"<<endl;
                                                                                                               else
                                                                                                                           cout<<"激活失败"<<endl;
                                                                                                           break;
                                                       case3:
                                                                                                          exit(0);
                                                       default:
                                                                           cout<<"选项不正确"<<endl;
                                                           }
     
    }
     
    }



     

    题目3    作业调度

     

    一、实验目的

    1、 对作业调度的相关内容作进一步的理解。

    2、 明白作业调度的主要任务。

    3、 通过编程掌握作业调度的主要算法。

    二、实验内容及要求

    1、对于给定的一组作业, 给出其到达时间和运行时间,例如下表所示:,

    作业名

    A

    B

    C

    D

    E

    F

    到达时间

    0

    2

    5

    5

    12

    15

    服务时间

    6

    50

    20

    10

    40

    8

     

     

     

     

     

    2、分别用先来先服务算法、短作业优先和响应比高者优先三种算法给出作业的调度顺序。

    3、计算每一种算法的平均周转时间及平均带权周转时间并比较不同算法的优劣。

    三、实验报告

    1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图。

    3、给出程序清单并附上注释。

    4、给出测试数据和运行结果。


    #include<iostream>
    using namespace std;
    #define MAX 10
    struct task_struct    {      
                   charname[10];          //进程名称     
                   intnumber;             //进程编号     
                  floatcome_time;         //到达时间    
               floatrun_begin_time;     //开始运行时间     
                  floatrun_time;           //运行时间   
               floatrun_end_time;       //运行结束时间
       int order;               //运行次序    
                  intrun_flag;             //调度标志   
    }tasks[MAX]; 
    int counter;                  //实际进程个数
    int fcfs();                     //先来先服务
    int sjf();              //短作业优先
    int hrrn();             //响应比高优先
    int pinput();            //进程参数输入
    int poutput();           //调度结果输出 
    void main() {
                                       intoption;
                                        pinput(); 
                                     while(true){
                                               printf("请选择调度算法(0~4):\n");
                                                                 printf("1.先来先服务\n");
                                                                 printf("2.短作业优先\n");
                                                             printf("3.响应比高优先\n");
                                                                           printf("0.退出\n");
                                                                       scanf("%d",&option);
                                                                              switch(option) { 
                                                                                             case0:      
                                                                                                             printf("运行结束。\n");    
                                                                                                             exit(0);
                                                                                                             break; 
                                                                                             case1:      
                                                                                                             printf("对进程按先来先服务调度。\n\n");     
                                                                                                             fcfs();     
                                                                                                             poutput();     
                                                                                                             break;
                                                                                             case2:             
                                                                                                             printf("对进程按短作业优先调度。\n\n");     
                                                                                                             sjf();      
                                                                                                             poutput();     
                                                                                                             break;
                                                                                             case3:      
                                                                                                             printf("对进程按响应比高优先调度。\n\n");    
                                                                                                             hrrn();     
                                                                                                             poutput();     
                                                                                                             break;
                                                                                                    }
                                             }
    } 
    int fcfs()   //先来先服务
    { 
                                 floattime_temp=0;
                                           inti; 
                                intnumber_schedul; 
                       time_temp=tasks[0].come_time;
                             for(i=0;i<counter;i++){    
                                                   tasks[i].run_begin_time=time_temp;    
                                              tasks[i].run_end_time=tasks[i].run_begin_time+tasks[i].run_time;   
                                                                          tasks[i].run_flag=1;    
                                                     time_temp=tasks[i].run_end_time;   
                                                                           number_schedul=i;    
                                                      tasks[number_schedul].order=i+1;
                                             } 
                                        return0;
    }  
     
    int sjf(){     //短作业优先  
                                 floattemp_time=0;
                                        inti=0,j; 
                      intnumber_schedul,temp_counter;
                                    floatrun_time; 
                          run_time=tasks[i].run_time;
                                           j=1; 
    while((j<counter)&&(tasks[i].come_time==tasks[j].come_time)){     
                                              if(tasks[j].run_time<tasks[i].run_time){        
                                                                                                             run_time=tasks[j].run_time;      
                                                                                                             i=j;     
                                                                                                    }    
                                                                                                j++;    
                                             }    
                          //查找第一个被调度的进程
                 //对第一个被调度的进程求相应的参数
                                 number_schedul=i;
    tasks[number_schedul].run_begin_time=tasks[number_schedul].come_time;
    tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time; 
                     tasks[number_schedul].run_flag=1; 
           temp_time=tasks[number_schedul].run_end_time;
           tasks[number_schedul].order=1;temp_counter=1;
                       while(temp_counter<counter) {    
                                                            for(j=0;j<counter;j++)     {         
                                                                                                           if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))         {   
                                                                                                                    run_time=tasks[j].run_time;
                                                                                                                    number_schedul=j;
                                                                                                                    break;
                                                                                                             }         
                                                                                                    }     
                                                          for(j=0;j<counter;j++)      {   
                                                                                                                   if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))          
                                                                                                                    if(tasks[j].run_time<run_time)              {      
                                                                                                                           run_time=tasks[j].run_time;                
                                                                                                                           number_schedul=j;             
                                                                                                                    }   
                                                                                                    }          
                                                              //查找下一个被调度的进程   
            //对找到的下一个被调度的进程求相应的参数  
          tasks[number_schedul].run_begin_time=temp_time;   
     tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time;    
                     tasks[number_schedul].run_flag=1;    
           temp_time=tasks[number_schedul].run_end_time;   
                                  temp_counter++;    
               tasks[number_schedul].order=temp_counter;  
                                             }
                                        return0;
    }  
    int hrrn() /*响应比高优先*/
    {  
                     intj,number_schedul,temp_counter; 
            floattemp_time,respond_rate,max_respond_rate;
                               //第一个进程被调度 
              tasks[0].run_begin_time=tasks[0].come_time;
    tasks[0].run_end_time=tasks[0].run_begin_time+tasks[0].run_time;
                     temp_time=tasks[0].run_end_time;
                                tasks[0].run_flag=1;
                                  tasks[0].order=1;
                       temp_counter=1;//调度其他进程
                        while(temp_counter<counter){
                                                                        max_respond_rate=0;
                                                                    for(j=1;j<counter;j++){
                                                                                                                   if((tasks[j].come_time<=temp_time)&&(!tasks[j].run_flag))
                                                                                                             {
                                                                                                                    respond_rate=(temp_time-tasks[j].come_time)/tasks[j].run_time;
                                                                                                                                           if(respond_rate>max_respond_rate){
                                                                                                                                                     max_respond_rate=respond_rate;
                                                                                                                           number_schedul=j;
                                                                                                                    }
                                                                                                             }
                                                                                                    }
                                                                        //找响应比高的进程
                                              tasks[number_schedul].run_begin_time=temp_time;
                                              tasks[number_schedul].run_end_time=tasks[number_schedul].run_begin_time+tasks[number_schedul].run_time;
                                              temp_time=tasks[number_schedul].run_end_time;
                                                    tasks[number_schedul].run_flag=1;
                                                                            temp_counter+=1;
                                              tasks[number_schedul].order=temp_counter;
                                             }
                                        return0;
    }
    int pinput() //进程参数输入
    {
                                           inti;
                       printf("请输入进程的数量:\n");
                              scanf("%d",&counter);
                              for(i=0;i<counter;i++)
                                             {
                                              printf("请输入第%d个进程信息  :\n",i+1);
                                                           printf("请输入进程名字:\n");
                                                                scanf("%s",tasks[i].name);
                                                           printf("请输入进程编号:\n");   
                                                          scanf("%d",&tasks[i].number);    
                                                    printf("请输入进程到达时间:\n");   
                                                      scanf("%f",&tasks[i].come_time);   
                                                    printf("请输入进程运行时间:\n");   
                                                        scanf("%f",&tasks[i].run_time);   
                                                                tasks[i].run_begin_time=0;   
                                                                   tasks[i].run_end_time=0;   
                                                                               tasks[i].order=0;   
                                                                          tasks[i].run_flag=0;
                                             } 
                                        return0;
    } 
    int poutput() //调度结果输出
    {
                                           inti; 
                       floatturn_round_time=0,f1,w=0; 
    printf("进程名字 进程编号 到达时间 运行时间 开始时间 结束时间  运行次序 周转时间\n");
                             for(i=0;i<counter;i++){    
                                              f1=tasks[i].run_end_time-tasks[i].come_time;   
                                                                      turn_round_time+=f1;   
                                                                w+=(f1/tasks[i].run_time);    
                                              printf("%s, %d, %5.3f, %5.3f, %5.3f, %5.3f, %d, %d,%5.3f\n",tasks[i].name,tasks[i].number,tasks[i].come_time,tasks[i].run_time,tasks[i].run_begin_time,tasks[i].run_end_time,tasks[i].order,f1);
                                             } 
    printf("平均周转时间=%5.2f\n",turn_round_time/counter);
           printf("平均带权周转时间=%5.2f\n",w/counter);
                                        return0;
    }


    题目4  基于优先数的时间片轮转调度算法调度处理器

     

    一、实验目的

    在采用多道程序设计的系统中,同时处于就绪态的进程往往有多个,当就绪态的进程数大于处理器的个数时,就需按照某种策略进行分配处理器。本次设计模拟在单处理器情况下采用基于优先数的时间片轮转调度算法进行处理器调度,加深了解处理器调度工作过程。

    二、实验内容及要求

    1、设计一个程序实现基于优先数的时间片轮转调度算法调度处理器。

    2、假定系统有5个进程,每个进程用一个进程控制块PCB来代表,进程控制块的结构如下图1.2所示:

     

    进程名

    指针

    到达时间

    要求运行时间

    已运行时间

    优先数

    进程状态

    图1

    其中:

    进程名:作为进程的标识。

    指针:进程按顺序排成循环链表,用指针指出下一个进程的进程控制块首地址,最后一个进程中的指针指出第一个进程的进程控制块首地址。

    要求运行时间:假设进程需要运行的单位时间数。

    已运行时间:假设进程已经运行的单位时间数,初值为0。

    状态:可假设有两种状态,就绪状态和结束状态。进程的初始状态都为就绪状态。

    3、每次运行所设计的处理器调度程序调度进程之前,为每个进程任意确定它的要求运行时间。

    4、此程序是模拟处理器调度,因此,被选中的进程并不实际启动运行,而是执行

    已运行时间+1

    来模拟进程的一次运行,表示进程已经运行过一个单位时间。

    .5、在所设计的程序中应有显示或打印语句,能显示或打印每次被选中的进程名以及运行一次后进程队列的变化。

    6、为进程任意确定要求运行时间,运行所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。

    7、设有一个就绪队列,就绪进程按优先数(优先数范围0-100)由小到大排列(优先数越小,级别越高)。当某一进程运行完一个时间片后,其优先级应下调(如优先数加2或3)。

    8、例如一组进程如下表:

    进程名

    A

    B

    C

    D

    E

    F

    G

    H

    J

    K

    L

    M

    到达时间

    0

    1

    2

    3

    6

    8

    12

    12

    12

    18

    25

    25

    服务时间

    6

    4

    10

    5

    1

    2

    5

    10

    4

    3

    15

    8


    三、实验报告

    1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图

    3、给出程序清单并附上注释

    4、打印程序运行时的初值和运行结果。(运行一个进程输出一次结果)

     

    //按优先数调度算法实现处理器调度的程序
     
    #include"stdio.h"
    #include"string.h" 
    #definenum 5//假定系统中进程个数为5
    structPCB
    { 
                                                charID;//进程名
                                        intruntime;//要求运行时间
                                                 intpri;//优先数
                                  char state; //状态,R-就绪,F-结束
     
    }; 
    structPCB pcblist[num];//定义进程控制块数组
     
     
    voidinit()//PCB初始化子程序
    {
                                                         int i; 
                                              for(i=0;i<num;i++) 
                                                           { 
                                                             printf("PCB[%d]:进程名 优先数 要求运行时间 \n",i+1);//为每个进程任意指定pri和runtime
                                                             scanf("%s%d%d",&pcblist[i].ID,&pcblist[i].pri,&pcblist[i].runtime);
                                                             pcblist[i].state='R';//进程初始状态均为就绪
                                                                                  getchar();//接收回车符
                                                           } 
    }
    intmax_pri_process()//确定最大优先级进程子程序
    { 
                       int max=-100;//max为最大优先数,初始化为-100
                                                         inti;
                                                       intkey; 
                                              for(i=0;i<num;i++) 
                                                           {
                                                            if(pcblist[i].state=='r')//r为辅助状态标志,表示正在运行
                                                                                                                           return-1;//返回-1
                                                                                                               else
                                                                                                                    if(max<pcblist[i].pri&&pcblist[i].state=='R')//从就绪进程中选取优先数最大的进程
                                                                                                                           { 
                                                                                                                                  max=pcblist[i].pri;//max存放每次循环中的最大优先数
                                                                                                                                  key=i;//将进程号赋给key 
                                                                                                                           }  
                                                           } 
             if(pcblist[key].state=='F')//具有最大优先数的进程若已运行完毕
                                                                                       return-1;//则返回-1
                                                     else//否则
                                                                returnkey;//将key作为返回值返回
    } 
    voidshow()//显示子程序
    {
                                                         inti; 
                     printf("\n 进程名 优先数 要求运行时间 状态 \n"); 
                     printf("-------------------------------------------------\n"); 
    for(i=0;i<num;i++)//依次显示每个进程的名、优先数、要求运行时间和状态
                                                           { 
                                                                                    printf("%s%6d%8d%s\n",&pcblist[i].ID,pcblist[i].pri,pcblist[i].runtime,&pcblist[i].state);
                                                           } 
                                printf(" pressany key to continue...\n");
    }
     
    voidrun()//进程运行子程序
    {
                                                        inti,j; 
                                            intt=0;//t为运行次数
                                              for(j=0;j<num;j++) 
                                                           {
                                                            t+=pcblist[j].runtime;}//运行次数即为各个进程运行时间之和
                                                            printf("\nbeforerun,the conditon is:\n"); 
                                                            show();//调用show()子程序显示运行前PCB的情况
                                                                            getchar();//等待输入回车符
                                                                                              for(j=0;j<t;j++)
                                                                                                                  {
                                                                                                                           while(max_pri_process()!=-1)//具有最大优先数的进程没有运行完,让其运行
                                                                                                                           {
                                                                                                                               pcblist[max_pri_process()].state='r';//将其状态置为r,表示其正在运行
                                                                                                                           }
                                                                                                                           for(i=0;i<num;i++) 
                                                                                                                           {
                                                                                                                                  if(pcblist[i].state=='r') 
                                                                                                                                  {
                                                                                                                                         pcblist[i].pri-=1;//将当前运行进程的优先数减1
                                                                                                                                         pcblist[i].runtime--;//要求运行时间减1
                                                                                                                                         {
                                                                                                                                                if(pcblist[i].runtime==0) 
                                                                                                                                                       pcblist[i].state='F';//运行完则将该进程状态置为结束
                                                                                                                                                else 
                                                                                                                                                       pcblist[i].state='R';//未运行完将其状态置为就绪
                                                                                                                                         }
                                                                                                                                         show();//显示每次运行后各PCB的情况
                                                                                                                                         getchar();//等待回车进入下一次运行
                                                                                                                                  }
                                                                                                                           }
     
                                                           }
    }
    voidmain()//按动态优先数调度主程序
    { 
                                       init();//初始化各个进程PCB
                                             run();//进程调度模拟
    } 
    



    题目5   银行家算法

     

    一、实验目的

    1、 对死锁避免中的银行家算法作进一步理解。

    2、 加深理解死锁的概念。

    3、 加深理解安全序列和安全状态的概念。

    4、 通过编程,掌握银行家算法分配资源的一步步实现过程。

    二、实验内容及要求

    1、给出系统可用资源向量(例如:系统可用资源=(5,3,8,2,10))。

    2、若干进程最大需求矩阵如下表所示:

    3、采用时间片轮转法调度进程。

    4、进程执行时提出资源请求(可利用随机数给出或从键盘输入)。

    5、判断资源是否可以安全分配,要求进程每提出一个资源请求,都要进行安全判断并给出安全序列,否则给出提示。

    三、实验报告

    1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图。

    3、给出程序清单并附上注释。

    4、给出测试数据和运行结果。


    #include<iostream>
    usingnamespace std;
    #defineMAXPROCESS 50                          //最大进程数
    #defineMAXRESOURCE 100                          //最大资源数
    intAvailable[MAXRESOURCE];                     //可用资源数组
    intMax[MAXPROCESS][MAXRESOURCE];             //最大需求矩阵
    intAllocation[MAXPROCESS][MAXRESOURCE];     //分配矩阵
    intNeed[MAXPROCESS][MAXRESOURCE];             //需求矩阵
    int Request[MAXPROCESS][MAXRESOURCE];          //进程需要资源数
    boolFinish[MAXPROCESS];                         //系统是否有足够的资源分配
    intp[MAXPROCESS];                              //记录序列
    intm,n;                                     //m个进程,n个资源
    voidInit(){                                                                                                                                                 //初始化算法
          int i,j;
          cout<<"请输入进程的数目:";
          cin>>m;
          cout<<"请输入资源种类的数目:";
          cin>>n;
          cout<<"请输入每个进程最大需求资源数矩阵:"<<endl;
          for(i=0;i<m;i++){
                                                                                          for(j=0;j<n;j++){
                                                                                                                           cin>>Max[i][j];
                                                                                                                 }
                                                            }
          cout<<"请输入每个进程已分配的各资源数矩阵:"<<endl;
          for(i=0;i<m;i++){            //判断输入的资源数是否合理
                                                                                          for(j=0;j<n;j++){
                  cin>>Allocation[i][j];
                 Need[i][j]=Max[i][j]-Allocation[i][j];//各进程尚需要的资源数
                  if(Need[i][j]<0){
                      cout<<"您输入的第"<<i+1<<"个进程的第"<<j+1<<"个资源数有错误,请重新输入:"<<endl;
                      j--;
                      continue;
                  }
              }
          }
          cout<<"请输入可利用资源向量矩阵:"<<endl;
          for(i=0;i<n;i++){
              cin>>Available[i];
          }
    }
    boolSafe(){                                     //判断安全函数
                                                    inti,j,k,l=0;
    int Work[MAXRESOURCE];                      //系统可提供给进程继续运行所需要的各类资源数目
                                                 for(i=0;i<n;i++)
                                                                                     Work[i]=Available[i];
                                               for(i=0;i<m;i++){
                                                                                              Finish[i]=false;
                                                           }
                                               for(i=0;i<m;i++){   
                                                                                        if(Finish[i]==true){
                                                                                                                           continue;
                                                                                                                  }
                                                                                                             else{
                                                                                                                           for(j=0;j<n;j++){
                                                                                                                                  if(Need[i][j]>Work[j]){
                                                                                                                                         break;
                                                                                                                                  }
                                                                                                                           }
                                                                                                                           if(j==n){
                                                                                                                                  Finish[i]=true;
                                                                                                                                  for(k=0;k<n;k++){
                                                                                                                                         Work[k]+=Allocation[i][k];
                                                                                                                                  }
                                                                                                                                  p[l++]=i;
                                                                                                                                  i=-1;
                                                                                                                           }
                                                                                                                           else{                 
                                                                                                                                  continue;
                                                                                                                           }
                                                                                                                  }
                                                            if(l==m){                                  //如果系统是安全的,将资源分配给进程
                                                                                                                           cout<<"此时系统是安全的"<<endl;
                                                                                                                           cout<<"安全序列为:"<<endl;
                                                                                                                           for(i=0;i<l;i++){
                                                                                                                                  cout<<p[i];
                                                                                                                                  if(i!=l-1){
                                                                                                                                         cout<<"-->";
                                                                                                                                  }
                                                                                                                           }
                                                                                                                           cout<<""<<endl;
                                                                                                                           returntrue;
                                                                                                                  }
                                                           }
                                cout<<"此时系统是不安全的"<<endl;
                                                    returnfalse;
    }
    voidBank()                  /*银行家算法*/
    {
          int i,cusneed;
          char again;
          while(1)
          {
              cout<<"请输入要申请资源的进程号(第1个进程号为0,依次类推)"<<endl;
              cin>>cusneed;
              cout<<"请输入进程的各资源需求矩阵"<<endl;
              for(i=0;i<n;i++)
              {
                  cin>>Request[cusneed][i];
              }
              for(i=0;i<n;i++)
              {
                 if(Request[cusneed][i]>Need[cusneed][i])
                  {
                      cout<<"您输入的请求数超过进程的需求量!请重新输入!"<<endl;
                      continue;
                  }
                 if(Request[cusneed][i]>Available[i])
                  {
                      cout<<"您输入的请求数超过系统拥有的资源数!请重新输入!"<<endl;
                                                                                                                                    continue;
                  }
              }
              for(i=0;i<n;i++)                           //假如系统将资源分配给p[i]
              {
                 Available[i]-=Request[cusneed][i];                     
                 Allocation[cusneed][i]+=Request[cusneed][i];
                 Need[cusneed][i]-=Request[cusneed][i];
              }
              if(Safe())               //执行判断是否安全函数
              {
                  cout<<"同意分配请求!"<<endl;
              }
              else
              {
                  cout<<"您的请求被拒绝!"<<endl;
                  for(i=0;i<n;i++)                  //不安全的,回复资源分配表
                  {
                     Available[i]+=Request[cusneed][i];
                     Allocation[cusneed][i]-=Request[cusneed][i];
                     Need[cusneed][i]+=Request[cusneed][i];
                  }
              }
              for(i=0;i<m;i++)
              {
                  Finish[i]=false;
              }
              cout<<"您还想再次请求分配吗?是请按y/Y,否请按其它键"<<endl;
              cin>>again;
              if(again=='y'||again=='Y')
              {
                  continue;
              }
              break;
              }
    }
    voidmain()
    {
          Init();
          Safe();
          Bank();
    }



    题目6   内存管理

     

    一、实验目的

    1、 对内存管理的相关内容做进一步的理解。

    2、 了解内存管理的主要任务。

    3、 了解内存管理任务的主要实现方法。

    4、 通过编程加深理解内存的分配、回收等主要算法的原理。

    二、实验内容及要求

    1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。

    2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表。

    3、在设计好的数据结构上设计一个主存分配算法,要求实现的基本功能操作有:寻找空闲分区,空闲分区表的修改,已分区表的修改。

    4、在设计好的数据结构上设计一个主存回收算法。其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。

    三、实验报告

    1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图。

    3、给出程序清单并附上注释。

    4、给出测试数据和运行结果,要求系统每进行一次分配或回收,都要给出内存映像图或已分配表及未分配表以观察内存的变化。


    程序代码

    #include<iostream>
    #include<vector>
    #include<fstream>
    #include<sstream>
    #include<string>
    usingnamespace std;
    typedefstruct node
    {
                                                       intID;                              //分区ID
              struct node *next;                   //指向下个分区的指针
                   float beginAddress;                  //分区起始地址
                       float length;                        //分区长度
                       int state;                           //分区状态
    }FQ;
    FQ*First=(FQ*)malloc(sizeof(FQ));      //头指针
    intFQCount=0;                           //分区个数
    intmaxID=0;         
     
    voiddisplay()         //打印内存初始分配状态
    {
                                          FQ*fqBegin=First->next;
                 cout<<"分区ID\t分区开始地址\t分区长度\t分区状态\n";
                                           while(fqBegin!=NULL)
                                                           {
                                                                                cout<<fqBegin->ID<<"\t"<<fqBegin->beginAddress<<"\t\t"<<fqBegin->length<<"\t\t"<<fqBegin->state<<endl;
                                                                                 fqBegin=fqBegin->next;
                                                           }
    }
    voidDistribute(float len)              //分配内存函数
    {
                                  FQ*temp=(FQ*)malloc(sizeof(FQ));                            
    temp=First;                                    //当前指针指向头指针
    while(!(temp->next->state==0&&temp->next->length>=len))     //此分区的状态为占用状态或者分区长度小于需要的长度
                                                           {
                                                               temp=temp->next;                    //考虑下一个分区
                                                           }
                                               temp=temp->next;
                                                 //  修改分区表
                                   FQ*fq1=(FQ*)malloc(sizeof(FQ));
                                              fq1->ID=++maxID;
                                            fq1->next=temp->next;
                           fq1->beginAddress=temp->beginAddress+len;
                                      fq1->length=temp->length-len;
                                                   fq1->state=0;
                                                temp->next=fq1;
                                               temp->length=len;
                                                  temp->state=1;
                             cout<<"分配内存后的内存状态:"<<endl;
                                                     display();
    }
    voidrecover(int id)               //回收内存函数
    {
       if (id>maxID)                      //判断想要回收的分区是否合理
                                                           {
                                                            cout<<"输入的id过大,没有与之匹配的分区"<<endl;
     
                                                           }
                                                         else{
                                                               FQ*temp=(FQ*)malloc(sizeof(FQ));      
                                                            temp=First;                          //当前指针指向头指针
                                                            while(!(temp->next->ID==id))        //寻找要回收的分区的id
                                                                                                                  {
                                                                                                                           temp=temp->next;
                                                                                                                  }
                                                            if(temp->state==0)                //分区状态为空闲时
                                                                                                                  {
                                                                                                                           if(temp->next->next==NULL)
                                                                                                                           {
                                                                                                                                  temp->next=NULL;
                                                                                                                                                temp->length=temp->length+temp->next->length;
                                                                                                                                  //若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
                                                                                                                           }
                                                                                                                           elseif(temp->next->next->state==1)
                                                                                                                           {
                                                                                                                                  temp->next=temp->next->next;
                                                                                                                                                temp->length=temp->length+temp->next->length;
                                                                                                                                  //若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
                                                                                                                           }
                                                                                                                           else
                                                                                                                           {
                                                                                                                           temp->length=temp->length+temp->next->length+temp->next->next->length;
                                                                                                                                  //若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
                                                                                                                                                        temp->next=temp->next->next->next;
                                                                                                                           }
                                                                                                                  }
                                                            else                 //分区被占用时
                                                                                                                  {
                                                                                                                                 if(temp->next->next==NULL||temp->next->next->state==1)
                                                                                                                           {
                                                                                                                                  temp->next->state=0;  //分区状态改为空闲
                                                                                                                           }
                                                                                                                           else
                                                                                                                           {
                                                                                                                                  temp->next->length=temp->next->length+temp->next->next->length;
                                                                                                                                  //若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里
                                                                                                                                                    temp->next->next=temp->next->next->next;
                                                                                                                                  temp->next->state=0;        //分区状态改为空闲
                                                                                                                           }
                                                                                                                  }
                                                            cout<<"回收内存后的内存状态:"<<endl;
     
                                                                                                       display();
                                                           }
    }
    int main()        //主函数
    {
                                           //初始化内存分区状态
                                                    fstreamfile;
       file.open("start.txt",ios_base::in|ios_base::out|ios_base::app);   //读写input.txt文件,读入最初的内存分配状态
                                                      strings0;
                 getline(file,s0);                //从输入流读取一行到s0
                   istringstream sin(s0);          //从s0中读取单个字符
                sin>>FQCount;                    //将sin向右位移6位
                                  FQ*temp=(FQ*)malloc(sizeof(FQ));     //定义当前指针
                                                    temp=First;
    for(string s;getline(file,s);)        //将文件中的分区起始地址,分区长度及分区状态读入程序
                                                           {
                                                                   FQ*fq=(FQ*)malloc(sizeof(FQ));
                                                                                        istringstreamsin(s);
                                                                                  sin>>fq->beginAddress;
                                                                                            sin>>fq->length;
                                                                                               sin>>fq->state;
                                                                                         fq->ID=++maxID;
                                                                                            fq->next=NULL;
                                                                                              temp->next=fq;
                                                                                                       temp=fq;
                                                           }
                               cout<<"最初的内存分配状态:"<<endl;
                                                     display();
                                                      while(1)
                                                           {
                                                            cout<<"请选择要进行的操作:\n1.请求分配内存 \n2.请求回收内存 \n3.退出\n";
                                                                                                     intchoice;
                                                                                                  cin>>choice;
                                                                                              switch(choice){
                                                                                                           case1:
                                                                                                                           cout<<"请求分配内存\n";
                                                                                                                           cout<<"请输入要分配的内存的长度:";
                                                                                                                           intlen;
                                                                                                                           cin>>len;
                                                                                                                           Distribute(len);
                                                                                                                           break;
                                                                                                           case2:
                                                                                                                           cout<<"请求回收内存\n";
                                                                                                                           cout<<"请输入要回收的内存的ID:";
                                                                                                                           intID;
                                                                                                                           cin>>ID;
                                                                                                                           recover(ID);
                                                                                                                           break;
                                                                                                           case3:
                                                                                                                           exit(0);
                                                                                                                           break;
                                                                                                         default:
                                                                                                                           cout<<"输入有误!请重新输入!\n";
                                                                                                                           continue;
                                                                                                                          
                                                                                                                  }
                                                           }
                                                      return0;
    }
     


     

     

    内存分区初始状态文件start.txt

    6

    0         500 1

    501      1000 0

    1501      2000 1

    3501      2500 0

    6001     4000 1

    10001     5000 0

     


    题目7     页面置换

     

    一、实验目的

    1、对页面置换做进一步的理解。

    2、了解页面置换的任务。

    3、通过编程掌握页面置换算法及缺页率。

    4、了解Belady现象和抖动现象。

    二、实验内容及要求

    1、任意给出一组页面访问顺序(如页面走向是1、2、5、7、5、7、1、4、3、5、6、4、3、2、1、5、2)。

    2、分配给该作业一定的物理块(如3块、4块等)。

    3、利用某几种页面置换算法模拟页面置换过程并计算其缺页率并分析结果。

    4、通过给出特殊的页面访问顺序,分配不同的物理块,利用FIFO算法计算其缺页率,进一步理解Belady现象。

    三、实验报告

        1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图。

    3、给出程序清单并附上注释。

    4、给出测试数据和运行结果,要求系统每进行一次页面置换,都要给出换进和换出的页面号。

    5、通过测试数据观察Belady现象。


    #include<stdlib.h> 
    #include<iostream.h>
    #include<time.h>
    void rand(intn,int p[])//这函数是产生n个1~10的随机数放到p[]数组里面
    {
                                           intSTART=1;
                                            intEND=10;
                                                 intv;
                                                  inti;
                                                 inta;
                                       srand(time(NULL));
                                         for(i=0;i<n;i++)
                                                    {
                                                       v=rand()%(END-START+1)+START;
                                                                                                   p[i]=v;
                                                                                                cout<<v;
                                                    }
    }
    struct Pro {
    int num,time; //num存放具体的内容,time在不同算法里面有不同的意义 
    };
    //它们是物理块和页面的数据结构
    int Input(intm,int N,Pro *p,Pro  *page)//完成p[]数组和page[]的初始化工作
    {
                  //p[]数组是存放页面的空间,m是页面的长度
                //page[]是可以使用的物理块,N是物理块的大小
                        cout<<endl<<"请输入各页面号"<<endl;
                                       int *p2=newint[m];
                                            rand(m,p2);
                                     for(inti=0;i<m;i++) {
                                                                                      p[i].num=p2[i];
                                                                                            p[i].time=0;
                                                    }
                       for(i=0;i<N;i++){ //初试化页面基本情况
                                                                                       page[i].num=0;
                                                                                page[i].time=N+2-i;
                                                    }
                                              returnm;
    }
    int Search(inte,Pro *page,int N)//算法里面都要用到它。
    {
            //它是找e页是否在page物理块中,N是物理块的大小 
                                       for(inti=0;i<N;i++)
                                                                                 if(e==page[i].num)
                                                                                                                    returni;//如果找到,就返回在物理块中的位置给Search
                                                                  return-1;//找不到,就返回-1
    }
    int Max(Pro*page,int N)//LRU算法用到的
    {
    //找出在page块中,time最大的值和位置,同时位置返回 //time最大,就代表了最久没被使用的数
                                    inte=page[0].time,i=0;
                                               intk=0;
                       while(i<N)//找出离现在时间最长的页面 
                                                    {
                                                                                 if(e<page[i].time){
                                                                                                       k=i;
                                                                                                           }
                                                                                                       i++;
                                                    }
                      cout<<"换出页面:"<<page[i].num<<endl;
                                               returnk;
    }
    int Compfu(Pro*page,int i,int t,Pro p[],int m)//OPT算法用到的
    {
    //找出如果page[t]要等于p,并且zai p[i]~p[m]这个区间内,走的次数,最大的数
                           int count=0;//count是保存走的步数
                                       for(intj=i;j<m;j++)
                                                    {
                                                                     if(page[t].num==p[j].num)
                                                                                                                    break;//如果相等,跳出循环
                                                                                                        else
                                                                                                                    count++;//不等就步数加1
                                                    }
                                            returncount;
    }
    int Min(Propage[],int N)//LFU算法用到的
    {
    //page[]是可以使用的物理块,N是物理块的大小 //找到出现次数最小的的数,并把位置返回
                                               intk=0;
                                     intmin=page[0].time;
                                       for(inti=0;i<N;i++)
                                                    {
                                                                               if(min>page[i].time)
                                                                                                                    k=i;
                                                    }
                                               returnk;
    }
    void FIFO(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
    {
                //page[]是可以使用的物理块,N是物理块的大小
                            float n=0;//n用来保存缺页的次数
                int i=0;//i是循环变量,它是表示走到页面的位置
                       int t=0;//t是用来表示物理块走到的位置
                             cout<<"页面置换情况:"<<endl;
                                         for(i=0;i<m;i++)
                                                    {
                                                               if(Search(p[i].num,page,N)>=0)
                                                                                                                    continue;//找到相同的页面,就跳到下一次循环,不做处理。
                                                     else//在找不到的时候,通过t=t%N,求出这次来替换物理块的位置   
                                                                                                           {     
                                                                                                                    cout<<"需要换进页面"<<p[i].num<<endl;
                                                                                                                    t=t%N;
                                                                                                                    cout<<"需要换出页面"<<p[t].num<<endl; 
                                                                                                                    n++;//缺页数加1   
                                                                                                                    page[t].num=p[i].num;           
                                                                                                                    t++;//位置加1
                                                                                                           } 
                                                    } 
    cout<<"缺页次数:"<<n<<"    缺页率:"<<n/m<<"    命中率:"<<1-n/m<<endl;   
    }       
    void LFU(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
    {   
              //page[]是可以使用的物理块,N是物理块的大小, 
                                              floatn=0; 
                                                inti=0; 
                                                intt=0;
                                         for(i=0;i<N;i++)  
                                                                                       page[i].time=0; 
                           cout<<"页面置换情况:   "<<endl; 
                                         for(i=0;i<m;i++) 
                                                    { 
                                                               if(Search(p[i].num,page,N)>=0)  
                                                                                                           {   
                                                                                                                    page[i].time++;//找到相同的页面,time加1   
                                                                                                                    continue;//  
                                                                                                           }  
                                                                                                        else    
                                                                                                           {
                                                                                                                    //找出使用最少的页面进行调换   
                                                                                                                    t=Min(page,N);//找到出现次数最小的的数,并把位置返回t   
                                                                                                                    page[t].num=p[i].num;   
                                                                                                                    page[t].time=0;//该页time清零   
                                                                                                                    n++;//缺页数加1   
                                                                                                           } 
                                                    }  
    cout<<"缺页次数:"<<n<<"    缺页率:"<<n/m<<"    命中率:"<<1-n/m<<endl;   
    }    
    void OPT(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
    {   
                //page[]是可以使用的物理块,N是物理块的大小      
                            float n=0;//n用来保存缺页的次数        
              int i=0;//i是循环变量,它是表示走到页面的位置。         
                       int t=0; //t是用来表示物理块走到的位置   
                                             while(i<m)   
                                                    {    
                                                               if(Search(p[i].num,page,N)>=0)     
                                                                                                                    i++;//如果找到了,就不做处理。    
                                                                                    else//如果找不到    
                                                                                                           {    
                                                                                                                     int temp=0,cn;//cn用来保存离后面最远的数     
                                                                                                                     for(t=0;t<N;t++)//对物理块里面的每个数进行遍历     
                                                                                                                     {      
                                                                                                                            if(temp<Compfu(page,i,t,p,m))//temp用来保存      
                                                                                                                            {
                                                                                                                                   //page[t]= p[i]~p[m]这个区间内,走的次数,最大的数        
                                                                                                                                   temp=Compfu(page,i,t,p,m);       
                                                                                                                                   cn=t;      
                                                                                                                            }     
                                                                                                                     }     
                                                          page[cn]=p[i];//把当前的值放要发生要走最远的数,也就最不可能最近出现的数   
                                                                            n=n+1;//缺页数加1     
                                                                         i++;//跳到下一次循环    
                                                                                                           }   
                                                    }   
     cout<<"缺页次数:"<<n<<"    缺页率:"<<n/m<<"    命中率:"<<1-n/m<<endl;   
    } 
    void LRU(Prop[],Pro page[],int m,int N)//p[]数组是存放页面的空间,m是页面的长度
    {   
      //page[]是可以使用的物理块,N是物理块的大小    
                            float n=0;//n用来保存缺页的次数 
              int i=0;//i是循环变量,它是表示走到页面的位置。 
                     int t=0;  //t是用来表示物理块走到的位置          
                              cout<<"页面置换情况:"<<endl;        
                                             while(i<m)    
                                                    {          
                                                  int k;
                                                                  k=t=Search(p[i].num,page,N);      
                                                                                                if(t>=0){      
                                                                                                                    page[t].time=0;//如果找到,就要把当前的page[t].time次数清零
                                                                                                           }
                                                               else//找不到的时候,发生缺页   
                                                                                                           {
                                                                                                                    cout<<"发生缺页,需换进页:"<<page[t].num<<endl;
                                                                                                                     n++; //缺页数加1        
                                                                                                                   t=Max(page,N);//找出page物理块里面,最久没被时候的数                      
                                                                                                                     //同时把最久没被时候的数在物理块里的位置传给t        
                                                                                                                     page[t].num=p[i].num;//最久没被使用的是被现在的数代替        
                                                                                                                     page[t].time=0;//同时清零    
                                                                                                           }         
                                                     for(intj=0;j<N;j++)//把缺页以外的数,把它没被使用的次数加1    
                                                                                                           {     
                                                                                                 if(j==t)      
                                                                                              continue;     
                                                                                     page[t].time++;     
                                                                                                           }          
                                                                            i++;//跳到下一次循环    
      }       
      cout<<"缺页次数:"<<n<<"    缺页率:"<<n/m<<"    命中率:"<<1-n/m<<endl;   
    }  
     
     void main()
     { 
                                         int m=0,t=0,N=0; 
                                  cout<<"请输入总页数:"; 
                                               cin>>m;      
                   Pro *p=new Pro[m];//p是用来放页面的地方    
                           cout<<"请输入物理块数:"<<endl; 
                                               cin>>N;      
                 Pro *page=new Pro[N];//page是放物理块的地方 
                                                  int c;   
                                              float n=0; 
          Input(m,N,p,page);//m是页面的总长,N是物理块的长度
                                         cout<<""<<endl;
                                            while(true){                    
                                                            cout<<"1:FIFO页面置换"<<endl;  
                                                             cout<<"2:LRU页面置换"<<endl;  
                                                             cout<<"3:OPT页面置换"<<endl;  
                                                             cout<<"4:LFU页面置换"<<endl;  
                                                                           cout<<"0:结束"<<endl;  
                                                                                                  cin>>c; 
                                                                                              switch(c){
                                                                                                   case1:      
                                                                                                                    FIFO(p,page,m,N);
                                                                                                                    break;
                                                                                                   case2:
                                                                                                                    LRU(p,page,m,N);
                                                                                                                    break;
                                                                                                   case3:
                                                                                                                    OPT(p,page,m,N);
                                                                                                                    break;
                                                                                                   case4:
                                                                                                                    LFU(p,page,m,N);
                                                                                                                    break;
                                                                                                   case0:
                                                                                                                    exit(0);
                                                                                                  default:
                                                        cout<<"没有与输入相匹配的操作,请重新输入"<<endl;
                                                                                                           }
     }
                                                    }



    题目8    磁盘调度

     

    一、实验目的

    1、对磁盘调度的相关知识作进一步的了解,明确磁盘调度的原理。

    2、加深理解磁盘调度的主要任务。

    3、通过编程,掌握磁盘调度的主要算法。

    二、实验内容和要求

    1、对于如下给定的一组磁盘访问进行调度:

    请求服务到达

    A

    B

    C

    D

    E

    F

    G

    H

    I

    J

    K

    访问的磁道号

    30

    50

    100

    180

    20

    90

    150

    70

    80

    10

    160

    2、要求分别采用先来先服务、最短寻道优先以及电梯调度方法进行调度。

    3、要求给出每种算法中磁盘访问的顺序,计算出平均移动道数。

    4、假定当前读写头在90号,向磁道号增加的方向移动。

    三、实验报告

    1、程序中使用的数据结构及符号说明。

    2、给出主要算法的流程图。

    3、给出程序清单并附上注释。

    4、给出测试数据和运行结果。


    #include "iostream.h"
    #include "math.h"
    //定义服务作业结构体
    struct jop{
                                                    charname;
                                                      intnum;
    };
    //初始化服务作业
    void intput_Rec(struct jop *p){
                                                 cin>>p->name;
                                                  cin>>p->num;
    }
    //交换服务作业算法
    void swap_Rec(struct jop *p1,struct jop*p2){
                                                    structjop x;
                                                       x=*p1;
                                                     *p1=*p2;
                                                       *p2=x;
    }
    //输出服务作业算法
    void put_Rec(struct jop *p){
                                             cout<<p->name<<'\t';
                                            cout<<p->num<<endl;
    }
    //先来先服务调度算法
    void FCFS(int mid,struct jop a[]){
                                cout<<"先来先服务调度算法"<<endl;
                                                         inti;
                                                     intsum=0;
                                   //按服务到达时间顺序访问并计算
                                                                                          for(i=0;i<11;i++){
                                                                                  mid=abs(a[i].num-mid);
                                                                                                    sum+=mid;
                                                                                       cout<<a[i].name<<"       ";
                                                                                        cout<<a[i].num<<"       ";
                                                            cout<<mid<<""<<endl;   //需要移动的磁道数
                                                           }
                         cout<<"平均移动道数"<<(double)sum/11<<endl;
    }
    //最短寻道优先算法
    void SSTF(int mid,struct jop a[]){
                                  cout<<"最短寻道优先算法"<<endl;
                                                     intsum=0;
                                                         inti;
                                               for(i=0;i<11;i++){
                                                                                        if(a[i].num==mid){      
    int flag=0;
                                                                                                                           ints=1;
                                                                                                                           intk;// 下标
                                                                                                                           k=i;
                                                                                                                           cout<<a[k].name<<"     ";
                                                                                                                           cout<<a[k].num<<"       ";
                                                                                                                           cout<<"0"<<endl;
                                                                                                                           for(s=1;s<11;s++){       
                                                                                                                                  if(flag=1){
                                                                                                                                         //第k-1个作业需要移动的磁道数大于k+s需要移动的磁道数
                                                                                                                                         if(abs(mid-a[k-1].num)>=abs(mid-a[k+s].num)){
                                                                                                                                                                          sum=sum+abs(a[k+s].num-mid);
                                                                                                                                                //输出k+s的作业信息
                                                                                                                                                cout<<a[k+s].name<<" ";
                                                                                                                                                cout<<a[k+s].num<<"  ";
                                                                                                                                                cout<<abs(mid-a[k+s].num)<<endl;
                                                                                                                                                //将磁道数比较值置为k+s的磁道号
                                                                                                                                                mid=a[k+s].num;
                                                                                                                                                flag=1;
                                                                                                                                                k=k+s;
                                                                                                                                         }
                                                                                                                                         //第k-1个作业需要移动的磁道数小于k+s需要移动的磁道数
                                                                                                                                         if(abs(mid-a[k-1].num)<abs(mid-a[k+s].num)){
                                                                                                                                                sum=sum+abs(a[k-1].num-mid);
                                                                                                                                                //输出k-1的作业信息
                                                                                                                                                cout<<a[k-1].name<<" ";
                                                                                                                                                cout<<a[k-1].num<<"   ";
                                                                                                                                                cout<<abs(mid-a[k-1].num)<<endl;
                                                                                                                                                //将磁道数比较值置为k-1的磁道号
                                                                                                                                                mid=a[k-1].num;
                                                                                                                                                flag=0;
                                                                                                                                                k=k-1;
                                                                                                                                         }
                                                                                                                                  }
                                                                                                                                  if(flag=0){
                                                                                                                                         //第k-s个作业需要移动的磁道数大于k+1需要移动的磁道数
                                                                                                                                         if(abs(mid-a[k-s].num)>=abs(mid-a[k+1].num)){
                                                                                                                                                                          sum=sum+abs(a[k+1].num-mid);
                                                                                                                                                //输出k+1的作业信息
                                                                                                                                                cout<<a[k+1].name<<" ";
                                                                                                                                                cout<<a[k+1].num<<"  ";
                                                                                                                                                cout<<abs(mid-a[k+1].num)<<endl;
                                                                                                                                                //将磁道数比较值置为k+1的磁道号
                                                                                                                                                mid=a[k+1].num;
                                                                                                                                                flag=1;
                                                                                                                                                k=k+1;
                                                                                                                                         }
                                                                                                                                         //第k-s个作业需要移动的磁道数小于k+1需要移动的磁道数
                                                                                                                                         if(abs(mid-a[k-s].num)<abs(mid-a[k+1].num)){
                                                                                                                                                sum=sum+abs(a[k-s].num-mid);
                                                                                                                                                //输出k-s的作业信息
                                                                                                                                                cout<<a[k-s].name<<"  ";
                                                                                                                                                cout<<a[k-s].num<<"   ";
                                                                                                                                                cout<<abs(mid-a[k-s].num)<<endl;
                                                                                                                                                //将磁道数比较值置为k-s的磁道号
                                                                                                                                                mid=a[k-s].num;
                                                                                                                                                flag=0;
                                                                                                                                                k=k-s;
                                                                                                                                         }
                                                                                                                                  }
                                                                                                                                  if(k<=0||k>=11)break;
                                                                                                                           }    
    if(k<=1){
                                                                                                                                  for(k=k+s+1;k<11;k++){
                                                                                                                                         sum=sum+abs(a[k].num-mid);
                                                                                                                                         cout<<a[k].name<<"     ";
                                                                                                                                         cout<<a[k].num<<"       ";
                                                                                                                                         cout<<abs(a[k].num-mid)<<endl;
                                                                                                                                         mid=a[k].num;
                                                                                                                                  }
                                                                                                                           }
                                                                                                                           break;    
                                                                                                                  }
                                                           }
                         cout<<"平均移动道数"<<(double)sum/11<<endl;                    
    }
    //电梯调度方法算法
    void SCAN(int mid,struct jop a[]){
                                  cout<<"电梯调度方法算法"<<endl;
                                                     intsum=0;
                                             for(inti=0;i<11;i++){
                                                                               //从中间向外访问磁道号
                                                                                          if(a[i].num>=mid)
                                                                                                                  {
                                                                                                                           intk;
                                                                                                                           //从中间访问到磁道号最大值
                                                                                                                           for(k=i;k<11;k++){
                                                                                                                                  sum+=a[k].num-mid;
                                                                                                                                  cout<<a[k].name<<"     ";
                                                                                                                                  cout<<a[k].num<<"       ";
                                                                                                                                  cout<<a[k].num-mid<<endl;
                                                                                                                                  mid=a[k].num;
                                                                                                                           }
                                                                                                                           //返回中间,再从中间访问到磁道号最小值
                                                                                                                           for(k=i-1;k>0;k--){      
                                                                                                                                  sum+=mid-a[k].num;
                                                                                                                                  cout<<a[k].name<<"     ";
                                                                                                                                  cout<<a[k].num<<"       ";
                                                                                                                                  cout<<mid-a[k].num<<endl;
                                                                                                                                  mid=a[k].num;
                                                                                                                           }
                                                                                                                           cout<<"平均移动道数"<<(double)sum/11<<endl;
                                                                                                                           break;
                                                                                                                  }
                                                           }
    }
    void main(){
                                                    inti=0,j=0;
                  intmid=90;      //最短寻到优先算法初始判断的磁道号
                                                     intsum=0;
                                              structjop *p1,a[11];
                                           cout<<"请输入"<<endl;
                                   cout<<"服务名称\t磁道号"<<endl;
                                          for(p1=a;p1<a+11;p1++){
                                                                                              intput_Rec(p1);
                                                           }
                                                  FCFS(mid,a);
                                          //为SCAN,SSTF作准备
                                               for(i=0;i<11;i++){
                                                                                       for(j=i+1;j<11;j++){
                                                                                                                           if(a[i].num>a[j].num)
                                                                                                                                  swap_Rec(&a[i],&a[j]);
                                                                                                                  }
                                                           }
                                                  SSTF(mid,a);
                                                  SCAN(mid,a);
    }


     

                           

     

     

    展开全文
  • 操作系统实验(一)

    千次阅读 2019-03-28 16:46:58
    操作系统实验 hello,我是橘子 最近突然发现我以前写的操作系统实验,然后分享给大家吧,就是自己写的代码也不是很好,希望大家见谅哈 实验目的 一、进程控制 ●基本要求:利用简单的结构和控制方法模拟进程结构、...

    操作系统实验

    hello,我是橘子
    最近突然发现我以前写的操作系统实验,然后分享给大家吧,就是自己写的代码也不是很好,希望大家见谅哈
    实验目的
    一、进程控制
    ●基本要求:利用简单的结构和控制方法模拟进程结构、进程状态和进程控制。
    ●参考学时:9学时
    ●实验提示:
    1、用PCB表示整个进程实体,利用随机数方法或键盘控制方法模拟进程执行中产生的事件,或者利用基于图形界面的鼠标或者键盘操作控制进程管理内容。
    2、定义PCB:包括理论PCB中的基本内容,如内部ID、外部ID、队列指针。由于很难实现真正的进程创建功能,在实验中只需建立PCB节点,并用它代表一个完整的进程。每创建一个进程时,可动态分配PCB节点,对相应内容赋值,并链接到适当的队列上。
    可参考如下数据结构(动态形式):
    struct PCB{
    char name[10];
    struct PCB*next;
    };
    struct PCB *ready,*blocked,running;
    创建进程时:
    struct PCB p=(struct PCB )malloc(sizeof(struct PCB));
    并将此进程添加到就绪队列末尾:
    add(ready,p);
    其中,ready为就绪队列头节点,并在开始处分配了空间;add函数是链表中添加节点函数,代码可以为:
    void add(struct PCB head,struct PCBprocess){
    struct PCB
    tmp=head;
    while(tmp->next!=NULL)
    tmp=tmp->next;
    tmp->next=process;
    process->next=NULL;
    }
    3、定义进程状态转换方式:真实的进程状态转换是由进程内部操作或操作系统的控制引起的。由于模拟程序中无法实现这些功能,我们可以采用随机数方法或键盘控制方法模拟,并实现对应的控制程序。随机方法指产生1-5的随机数,分别代表创建进程(1)、时间片到(2)、进程阻塞(3)、唤醒进程(4)、结束进程(5)等事件;键盘模拟方法指定义5个选项菜单代表以上五种事件。
    4、根据随机数或键盘操作处理就绪队列、阻塞队列和当前执行进程的状态。每次事件处理后应显示出当前系统中的执行进程是哪一个,就绪队列和阻塞队列分别包含哪些进程。
    5、
    (带
    部分为试验班和特长班需要完成的内容,普通班选作)完成可变分区的分配与回收,创建进程的同时申请一块连续的内存空间,结束进程同时回收分配的内存空间。分配采用最佳适应算法,碎片大小为2Kb,最后回收所有进程的空间。可以查看进程所占的空间和系统空闲空间。
    ●评分标准:满分15分
    要求必须完成以下几个方面的内容:
    能够模拟进程的创建与撤销过程;5分
    可对进程的状态进行全面的控制;5分
    按先进先出方式管理就绪和阻塞队列,能够按队列形式输出进程状态。5分

    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    typedef struct PCB
    {
    	char data;
    	struct PCB *next;
    }PCB,*PCBlist;
    void show(PCBlist rear)//就绪状态和堵塞状态展示
    {
    	PCBlist P=rear;
    	while(P->next)
    	{
    		cout<<P->next->data<<" ";
    		P=P->next;
    	}
    }
    void runshow(char running)//执行状态展示
    {
    	if(running=='\0')
    		cout<<"没有正在执行的进程"<<endl;
    	else
    		cout<<running<<endl;
    }
    void add(PCBlist rear,char ch)//尾插法插入
    {
    	PCBlist P=rear;//队列头
    	PCBlist s=new PCB;//新建节点
    	s->data=ch;
    	s->next=NULL;
    	if(P->next==NULL)//进程链为空添加节点
    	{
    		P->next=s;
    	}
    	else
    	{
    		while(P->next!=NULL)//进程链不为空添加节点
    		{
    			P=P->next;
    		}
    		P->next=s;
    	}
    }
    void menu()//进程选择菜单
    {
    	//cout<<"请选择执行的操作:"<<endl;
    	cout<<"1.创建进程"<<endl;
    	cout<<"2.时间片到"<<endl;
    	cout<<"3.进程阻塞"<<endl;
    	cout<<"4.唤醒进程"<<endl;
    	cout<<"5.结束进程"<<endl;
    }
    void showall(PCBlist ready,PCBlist block,char running)//进程状态显示
    {
    	cout<<"----------------------------------"<<endl;
    	cout<<"就绪状态为:";
    	show(ready);
    	cout<<endl;
    	cout<<"执行状态为:";
    	runshow(running);
    	cout<<"阻塞状态为:";
    	show(block);
    	cout<<endl;
    	cout<<"----------------------------------"<<endl;
    }
    void main()
    {
    	PCBlist S;//释放空间
    	int n;
    	char running ='\0';
    	char ch,temp;// ch为输入进程的名字
    	PCBlist ready=new PCB;
    	PCBlist block=new PCB;
    	ready->next=NULL;
    	block->next=NULL;
    	PCBlist rear1=block;
    //	PCBlist pc=ready;
    
    //	PCBlist pd=block;
    	showall(ready,block,running);
    log:{
    	menu();
    	cout<<"请选择执行的操作:"<<endl;
    	}
    	cin>>n;
    	while(true)
    	{	
    		system("cls");
    		menu();
    		switch(n)
    		{
    		case 1://创建进程
    			{
    				cout<<"请输入进程名";
    				cin>>ch;
    				add(ready,ch);
    				//显示:
    				if(running=='\0')//如果还没有正在执行的进程
    				{
    					if(ready->next!=NULL)//就绪队列不为空
    					{
    						temp=ready->next->data;//获取队头进程(就绪队列第一个元素)
    						S=ready->next;
    						ready->next=ready->next->next;//出队头
    						delete S;
    						running=temp;//将就绪状态变为执行状态
    					}
    					showall(ready,block,running);
    				}
    				else
    				{
    					showall(ready,block,running);
    				}
    				break;
    			}
    		case 2://时间片到
    			{
    				if(running!='\0')
    				{
    					add(ready,running);//将正在执行的进程添加到就绪状态中
    					
    					if(ready->next!=NULL)
    					{
    						temp=ready->next->data;
    						S=ready->next;
    						ready->next=ready->next->next;
    						delete S;
    						running=temp;
    					}//将此时就绪队列的队头变为执行状态
    					else
    					{
    						running='\0';
    					}
    					showall(ready,block,running);
    				}
    				else
    				{
    					cout<<"没有正在进行的进程"<<endl;
    				}
    				break;
    			}
    		case 3://进程阻塞
    			{
    				if(running=='\0')
    					cout<<"没有正在进行的进程"<<endl;
    				else
    				{
    					add(block,running);//将阻塞的进程添加到阻塞队列
    				
    					if(ready->next!=NULL)
    					{
    						temp=ready->next->data;
    						S=ready->next;
    						ready->next=ready->next->next;
    						delete S;
    						running=temp;
    					}//将此时就绪队列的队头变为执行状态
    					else
    					{
    						running='\0';
    					}
    					showall(ready,block,running);
    				}
    				break;
    			}
    		case 4://唤醒进程
    			{
    				if(block->next==NULL)
    					cout<<"没有正在阻塞的进程"<<endl;
    				else
    				{
    					cout<<"请输入要唤醒的进程"<<endl;
    					cin>>ch;
    					
    					while(rear1->next->data!=ch)//找到要唤醒的进程
    					{
    						if(rear1->next->next!=NULL)
    						{
    							rear1=rear1->next;
    						}
    						else
    						{
    							cout<<"未查询到该进程"<<endl;
                                showall(ready,block,running);
    							goto log;
    						}
    
    					}
    					add(ready,rear1->next->data);//将要唤醒的进程添加到就绪队列中
    					if(rear1->next->next!=NULL)//判断此节点后面是否还存在节点
    					{
    					    S=rear1->next ;
    					    rear1->next=rear1->next->next;//删除刚才节点
    						delete S;
    					}
    					else
    					{
                            rear1->next=NULL;
    					}
    					if(running=='\0')//如果没有正在执行的进程
    				    {
    						if(ready->next!=NULL)
    						{
    							temp=ready->next->data;
    							running=temp;
    							S=ready->next;
    							ready->next=ready->next->next;
    							delete S;
    						}
    					   showall(ready,block,running);
    					}
    					else
    					{
    						 showall(ready,block,running);
    					}
    					
    				}
    				
    				break;
    			}
    		case 5://结束进程
    			{
    				//ws/cout<<"请输入要结束的进程号";
    				//cin>>q;
    				//while(pc->next!=NULL)//在就绪队列中找要结束的进程
    				//{
    				//	if(pc->next->data==q)
    				//	{
    				//		pc->next=pc->next->next;
    				//		showall(ready,block,running);
    				//		break;
    				//	}
    				//	else
    				//		pc=pc->next;
    				//}
    				//while(pd->next!=NULL)//在阻塞队列中找要结束的进程
    				//{
    				//	if(pd->next->data==q)
    				//	{
    				//		pd->next=pd->next->next;
    				//		showall(ready,block,running);
    				//		break;
    				//	}
    				//	else
    				//		pd=pd->next;
    				//}
    				//if(running==q)//如果要结束的进程正在执行
    				//{
    					running='\0';
    					if(ready->next!=NULL)
    					{
    						
    						temp=ready->next->data;
    						S=ready->next;
    						ready->next=ready->next->next;
    						running=temp;
    						delete S;
    					}
    					showall(ready,block,running);
    				/*}*/
    			}
    		}
    		cout<<"请选择执行的操作:"<<endl;
    		cin>>n;
    	}
    }
    
    
    
    展开全文
  • 1.实验目的 学会通过基本的Linux进程控制函数创建子进程,并实现协同工作。创建两个进程,让子进程读取输入,父进程等待子进程读完文件后继续执行。2.实验软硬件环境安装Windows7的计算机VMware软件,在其上安装有...

    供大家交流学习,最好自己动手做,这样才有最深切的体会。


    1.实验目的

        学会通过基本的Linux进程控制函数创建子进程,并实现协同工作。创建两个进程,让子进程读取输入,父进程等待子进程读完文件后继续执行。


    2.实验软硬件环境
    • 安装Windows7的计算机
    • VMware软件,在其上安装有Ubuntu虚拟机

    3.实验内容

    1.掌握vfork()、fork()、waitpid()等函数的使用。

    2.用以上函数在Linux操作系统创建子进程,子进程创建文件,父进程等待子进程完成后读取文件,并使父子进程分别修改资源,了解vfork()和fork()的区别。

    相关函数介绍:

    • pid_t  vfork(void) 
      创建进程但子进程共享父进程的地址空间,即子进程对资源的改变会影响父进程,且强制优先子进程运行,父进程被阻塞,只有当子进程运行完后父进程才能运行。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1。
    • pid_t  fork(void) 
      子进程只是父进程的简单拷贝,子进程对资源的改变不会影响父进程,且父子进程可以并发运行。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1。
    • pid_t waitpid(pid_t pid,int * status,int options)                                                                                                  waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 waitpid()时子进程已经结束,则 waitpid()会立即返回子进程结束状态值。 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一起返回。如果不在意结束状态值,则参数 status 可以设成 NULL。参数 pid 为欲等待的子进程识别码,其他数值意义如下:                                                                                                                                              pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。                                                                                   pid=-1 等待任何子进程,相当于 wait()。                                                                                                               pid=0 等待进程组识别码与目前进程相同的任何子进程。                                                                                           pid>0 等待任何子进程识别码为 pid 的子进程。                                                                                                         参数options提供了一些额外的选项来控制waitpid,参数 option 可以为 0 或可以用"|"运算符把它们连接起来使用,比如:ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);如果我们不想使用它们,也可以把options设为0,如:ret=waitpid(-1,NULL,0);WNOHANG 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若结束,则返回该子进程的ID。WUNTRACED 若子进程进入暂停状态,则马上返回,但子进程的结束状态不予以理会。WIFSTOPPED(status)宏确定返回值是否对应与一个暂停子进程。
    • pid_t  getpid(void) 
      返回子进程的pid。
    • pid_t  getppid(void) 
      返回父进程的pid,因为系统分配pid的时候遵循相邻递增的原则,所以一般子进程的pid比父进程的pid大1

    4.实验程序及分析

    实验程序:

    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<unistd.h>
    //创建子进程fork()是简单的拷贝,而vfork()类似于线程,强制执行子进程让父进程阻塞,在子进程执行exit前子进程共享父进程的数据,子进程结束后在运行父进程。
    int main()
    {
    	pid_t child;
    	int i=0;
    	printf("i = %d\n",i);
    	char str[50];
    	puts("1.excute");
    	child = vfork();
    	//child = fork();
    //无论父子进程都是从fork或vfork后运行的,fork创建了子进程后,在子进程中返回0,在父进程中返回子进程的pid。
    
    	puts("2.excute");
    	
    	if(child== -1)
    	{
    		perror("fork");
    		puts("fail to create a sup process");
    		exit(1);
    	}
    	else if(child == 0)
    	{
    		puts("\nin child:");
    		printf("\tchild pid = %d\n",getpid());
    		printf("\tchild ppid = %d\n",getppid());
    		puts("writing in file :\n This is my work\n");
    		FILE  *fp = fopen("123.txt","w");
    		fprintf(fp,"%s","This is my work");		
    		fclose(fp);
    		i++;
    		printf("i = %d\n",i);
    		exit(0);
    	}
    	else
    	{
    		waitpid(child,NULL,0);
    //等待pid为child的子进程运行,当子进程运行完后父进程运行。
    		puts("\nin parent:");
    		puts("reading form file ...");
    		FILE *fp = fopen("123.txt","r");
    		fgets(str,50,fp);
    		puts(str);
    		fclose(fp);
    		i++;
    		printf("i = %d\n",i);
    		exit(0);
    	}
    	return 0;
    }

    终端结果:

    vfork():

    fork():


    分析:

    由以上代码,分别运行vfork()和fork()函产生子进程的结果有所不同,通过这些可以知道:

    • vfork()创建子进程后强制优先执行子进程,将父进程阻塞,只有当子进程运行完之后才运行父进程的代码。所以vfork()的运行结果中子进程的2.excute和父进程的2.excute没有连在一起。而是分开了。又因为父子进程是共享地址空间的,故子进程对i++的操作会影响父进程,父进程中输出i=2.
    • fork()运行结果就与vfork()不同了。因为fork()是对父进程的简单拷贝,且可以与父进程并发执行。故子进程的2.excute和父进程的2.excute连在一起。且子进程中i++对父进程没有影响,故父进程中的i=1.父进程中waitpid()函数使得父进程在运行else分支代码前要等待子进程。

    5.实验截图

    fork()

    vfork()



    6.实验心得体会
    这次实验让我掌握了如何Linux在创建子进程,并且较为深入的了解了fork()和vfork()的区别。fork()创建的子进程只是对父进程的简单拷贝,并且父子进程并发执行。vfork()创建的子进程共享父进程的地址空间,且父进程被阻塞,只有当子进程运行完成后才能执行。



    展开全文
  • 计算机操作系统实验一:进程调度

    千次阅读 多人点赞 2019-04-24 09:34:29
    一、实验目的 编写并调试一个模拟的进程调度程序,以加深对进程的概念及进程调度算法的理解. 二、实验内容 调试运行“动态优先级”调度算法,给出运行结果。 采用“短进程优先”调度算法对五个进程进行调度。每个...
  • 操作系统实验

    千次阅读 2018-03-14 12:54:22
    是 “操作系统原理”课内上机实验指导书 适用专业:计算机科学与技术计算机软件技术 电子与信息工程学院计算机系2012年6月前 言操作系统原理是计算机专业本科学生的必修课程,它具有较强的理论性和实践性。...
  • 操作系统实验报告

    万次阅读 2018-08-18 09:38:11
    实验名称 Linux 进程创建 专业 软件工程 姓名   学号 ... 实验目的: ...练习使用fork()系统调用创建进程 ...练习Linux操作...
  • 操作系统实验1

    千次阅读 2019-06-26 18:09:58
    操作系统 实验报告 题目: 实验1 学生姓名: 周思宇 学生学号: 201608030201 ...
  • 操作系统实验指导书(完整版)

    万次阅读 多人点赞 2016-05-25 11:32:22
    操作系统实验指导书               烟台大学计算机学院 操作系统课程组 2008-9-20             第一部分 操作系统上机指导   Linux操作系统环境: RedHat Enterprise Linux ES ...
  • 出于简单起见,该文件系统是基于内存的,以下是各个文件:   1、内存资源管理(Disk.h, Disk.cpp) 2、文件读写接口(File.h, File.cpp) 3、主程序(main.cpp, my_shell.cpp) 目录项数据结构:   一个目录项...
  • 操作系统实验:进程的创建

    万次阅读 2018-05-28 22:28:55
    实验名称:进程的创建实验一、实验目的:1. 加深对进程概念的理解,明确进程和程序的区别。进一步认识并发执行的实质。2. 认识进程生成的过程,学会使用fork生成子进程,并知道如何使子进程完成与父进程不同的工作...
  • 实验报告一:Linux安装及环境熟悉

    千次阅读 2016-09-09 18:19:58
    实验报告一 课程名称 Unix/Linux系统设计 实验日期 2016.9.4 实验项目名称 Linux安装及环境熟悉 实验地点 实验类型 √验证型□设计型□综合型 ...
  • Linux基本操作命令 实验

    千次阅读 2018-04-29 18:09:55
    2. 熟悉Linux操作系统。二、实验环境:一台装有Linux的机器。三、实验内容:1.文件操作命令的使用。用vi编辑器新建一个testl文件输入this is testl~!查看文件与目录ls进入Linux系统,输入ls-m按回车键执行。 一、...
  • 操作系统实验四——进程调度

    万次阅读 多人点赞 2018-06-02 10:18:10
    设计一个程序,根据不同的调度算法模拟操作系统对进程的调度。 动态优先级法 1、 设计进程控制块PBC表结构,分别适用优先数调度算法 2、 PBC结构通常包括以下信息:进程名、进程优先数、轮转时间片、进程的CPU时间...
  • 嵌入式实验报告(linux实验

    千次阅读 2018-06-27 11:22:33
    1 LED 灯驱动程序1.1 “文件”的实现设备驱动作为操作系统的一部分,是操作系统对设备进行操作的接口。操作系统规定了设备驱动需要实现的接口,而我们在裸机实验中也用到了控制设备所用到的接口。为了实现我们嵌入式...
  • LINUX安装实验报告

    千次阅读 2017-10-17 09:47:33
    实验目的: 1、 掌握虚拟软件 VMware ...3、掌握Linux操作系统下与Windows操作系统下的不同分区方案。 实验步骤: 1、 安装虚拟机 2、 新建虚拟机 3、进入虚拟机安装向导  4、安装CentO
  • 实验二:进程的控制 1 .实验目的 通过进程的创建、撤消和运行加深对进程概念和进程并发...没有建立进程的程序不能作为1个独立单位得到操作系统的认可。 (3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进...
  • Linux 系统实验报告:实验二

    千次阅读 2017-03-17 18:24:58
    Linux内核编译实验报告 报告提交日期:2017.03.17 报告提交截止日期:2017.03.15 姓名:曾鑫星 学号:1505010615 班级:计算机科学与技术6班 一、 实验题目 Linux内核的编译和安装 二、 实验目的 1....
  • Linux进程控制实验报告

    万次阅读 2018-05-30 23:03:27
    二、实验环境:一台至少具有256MB内存的计算机,并安装Red Hat Linux 9的Linux操作系统。三、实验内容:(写出主要的内容)1. 预备知识fork函数调用:创建一个新进程。getpid函数调用:获得一个进程的pid。lockf系统...
  • 最近想学习下关于操作系统的课程,无意中在学堂在线上发现了清华大学的操作系统这门课,讲得实在是太好了,我们学校跟它比真是差太远了,清华大学的老师讲课很有条理,很清晰,让人很容易接受! 不过今天在搭建那个...
1 2 3 4 5 ... 20
收藏数 331,229
精华内容 132,491
关键字:

操作系统实验