操作系统实习报告

目录

一、 进程调度 2

1. 短作业优先调度算法 2

1.1题目内容 2

1.2题目要求 2

1.3设计思想 3

1.4算法分析 3

1.4.2程序结构 3

1.4.2数据结构 3

1.5核心代码 5

1.6程序流程图 6

1.7测试数据或截图 6

2. 时间片轮转调度算法 7

2.1题目内容 7

2.2题目要求 7

2.3设计思想 7

2.4算法分析 8

2.4.1程序结构 8

2.4.2数据结构 8

2.5核心代码 9

2.6程序流程图 11

2.7测试数据或截图 12

二、 磁盘调度管理 12

1. 题目内容 12

2. 题目要求 12

3.设计思想 13

4.算法分析 13

4.1程序结构 13

4.2数据结构 13

5.核心代码 15

7.测试数据或截图 17

三、 心得体会 18

 

 

 

一、进程调度

1. 短作业优先调度算法

1.1题目内容

设计程序模拟单处理机系统中的进程调度算法,在短作业优先调度算法、 时间片轮转调度、最高优先级优先算法三种算法中选择两种实现。

1.2题目要求

每个进程由一个进程控制块(PCB)表示。进程控制块可以包含如下信息: 进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数 产 生)。进程的到达时间为进程输入的时间。

进程的运行时间以时间片为单位进行计算。

每个进程的状态可以是就绪W(Wait)、运行R(Run)或完成F(Finish)3 中状态之一。

1.3设计思想

该算法先比较作业运行时间长短,运行时间短的作业先执行,如果运行 时间相同,则按照到到达时间执行,到达时间早的先执行。

1.4算法分析

1.4.1程序结构

①输入部分:

void input(PCB *p,int N)

{

int i;

printf("请输入进程的名称、到达时间和运行时间:\nfor example:a 0 100\n");

for(i=0;i<=N-1;i++)

{

printf("请输入第%d个进程的信息:\n",i+1); scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i].runtime);

}

}

②输出部分:

oid output(PCB *p,int N)

{

int k;

printf("优先运行顺序:");

printf("%s",p[0].name); for(k=1;k<N;k++)

{

printf("-->%s",p[k].name); }

printf("\n各个进程的信息:\n");

printf("\n名称\t到达\t运行\t开始\t完成\t周转\t带权周转 \n");

for(k=0;k<N;k++)

{

printf("%s\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t\n",p[k]. name,p[k].arrivetime,p[k].runtime,p[k].starttime,p[k].finishtim e,p[k].zztime,p[k].dqzztime);

}

}

③排序部分:用冒泡排序法将到达时间降序排序

void sort(PCB *p,int N)

{

for(int i=0;i<N;i++)

for(int j=0;j<i;j++)

if(p[i].arrivetime<p[j].arrivetime) {

PCB t;

t=p[i];

p[i]=p[j];

p[j]=t;

}

}

④计算部分:为了得到每个进程的结束时间

void deal(PCB *p,int N)/{

int k;

 

for(k=0;k<N;k++)

{

if(k==0) {

p[k].starttime=p[k].arrivetime;

p[k].finishtime=p[k].starttime+p[k].runtime;

}

else

{

p[k].starttime=p[k-1].finishtime;

p[k].finishtime=p[k].starttime+p[k].runtime;

}

}

for(k=0;k<N;k++)

{

p[k].zztime=p[k].finishtime-p[k].arrivetime;

p[k].dqzztime=p[k].zztime/p[k].runtime;

}

}

1.4.2数据结构

struct PCB

{

char name[10];

float arrivetime;

float runtime;

float starttime;

float finishtime;

float zztime;

float dqzztime;

};

PCB a[100];

1.5核心代码

void sjff(PCB *p,int N)

{

float arrivetime=0,runtime=0,starttime=0,finishtime=0,zztime=0,dqzztime=0;

sort(p,N);

   for(int m=0;m<N-1;m++)

{

if(m==0)

        p[m].finishtime=p[m].arrivetime+p[m].runtime;         else

{

if(p[m-1].finishtime >=p[m].arrivetime )

{

p[m].starttime=p[m-1].finishtime;}/

else

{

p[m].starttime =p[m].arrivetime;}

   p[m].finishtime=p[m].starttime+p[m].runtime;

}

int i=0;

        for(int n=m+1;n<=N-1;n++)

{

if(p[n].arrivetime<=p[m].finishtime)

            i++;

}

        float min=p[m+1].runtime;

        int next=m+1;//m+1=n

        for(int k=m+1;k<m+i;k++)

{

          if(p[k+1].runtime<min)

          {

  min=p[k+1].runtime;

              next=k+1;

  }

}

            PCB temp;

            temp=p[m+1];

            p[m+1]=p[next];

            p[next]=temp;

}

   deal(p,N);

   output(p,N);

}

 


1.6程序流程图


    1.7测试数据或截图操作系统实习报告

 操作系统实习报告

 

2. 时间片轮转调度算法

2.1题目内容

      设计程序模拟单处理机系统中的进程调度算法,在短作业优先调度算法、时间片轮转调度、最高优先级优先算法三种算法中选择两种实现。    

2.2题目要求  

         每个进程由一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等。

进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。

进程的运行时间以时间片为单位进行计算。

每个进程的状态可以是就绪W(Wait)、运行R(Run)或完成F(Finish)3中状态之一。

2.3设计思想

该算法按照先来先服务执行进程,用time()函数计算进程运行时间,先将 进程初始化信息进行备份,用while条件判断进程是否全部执行完毕,如果进 程执行完毕则跳出循环结束计算。

2.4算法分析:

  2.4.1程序结构

①输入函数:

int pinput() /*进程参数输入*/

{

    int i;

    printf("请输入进程个数:\n");

    scanf("%d",&counter);

    printf("请输入时间片长度:\n");

    scanf("%d",&timecounter);

    for(i=0; i<counter; i++)

    {

     printf("**************************************\n");

printf("请输入进程名称、到达时间、运行时间:(中间用 空格隔开)\n");

scanf("%s%f%f",tasks[i].name,&tasks[i].arrivetime,& tasks[i].runtime);

        tasks[i].starttime=0;

        tasks[i].finishtime=0;

        tasks[i].runflag=0;  //运行是否结束

        tasks[i].startflag=0;//是否首次被执行

    }

    return 0;

}

②输出函数:

int poutput()

{

    int i;

    float dqzztime=0,zztime=0,w=0;

    printf("进程名 到达时间 运行时间 开始时间 结束 时间 周转时间 带权周转时间\n");

    for(i=0; i<counter; i++)

    {

         zztime=tasks[i].finishtime-tasks[i].arrivetime;

        dqzztime=zztime/tasks[i].runtime;

     printf("%s\t%5.3f\t%5.3f\t%5.3f\t %5.3f\t%5.3f\t%5.3 f\n",tasks[i].name,tasks[i].arrivetime,tasks[i].run time,tasks[i].starttime,tasks[i].finishtime,zztime, dqzztime);

    }

    return 0;

}

③判断函数:判断进程是否全部执行完毕

int charge()

{

    int k;

    int superflag=0;

    for(k=0; k<counter; k++)

    {

        if(tasks[k].runflag==0)

        {

            superflag=1;

            return superflag;

            break;

        }

        else

        {

            superflag=0;

        }

    }

    return superflag;

}

2.4.2数据结构

struct task_struct

{

    char name[10];           /*进程名称*/

    float arrivetime;         /*到达时间*/

    float starttime;     /*开始运行时间*/

    float runtime;          /*运行时间*/

    float finishtime;      /*运行结束时间*/

    int runflag;          /*调度标志*/

    int startflag;     //是否为第一次开始调度

} tasks[MAX];

int counter; /*实际进程个数*/

int pinput();

int timecounter=0;

int poutput(); /*调度结果输出*/

int time();

int charge();//判断是否所有的进程都被执行过

2.5核心代码

int time()

{

    float temp=0;

    int i;

    int j=0;

    int k=0;

    struct task_struct  copy_task[MAX];//备份

    for(i=0; i<counter; i++)

    {

        copy_task[j++]=tasks[i];//对进程的初始化信息备份

    }

    temp=tasks[0].arrivetime;//temp=第一个进程的到达时间

    while(charge())

    {

        for(i=0; i<counter; i++)

        {

            if(tasks[i].arrivetime>temp)

            {

                temp=tasks[i].arrivetime;

            }

            if(tasks[i].runflag==0)//第i个进程还未结束

            {

                if(tasks[i].startflag==0)  

                {

                    tasks[i].starttime=temp;

                    tasks[i].startflag=1;

                }

                if(tasks[i].runtime/timecounter>1)

                {

                    tasks[i].runtime=tasks[i].runtime-timecounter;

                    temp=temp+timecounter;

                }

                else if(tasks[i].runtime-timecounter==0)

                {

                    temp=temp+timecounter;                     tasks[i].finishtime=temp;

                    tasks[i].runflag=1;//标记该进程已经执行完毕

                    tasks[i].runtime=copy_task[i].runtime;

                }

                else//仅剩下不足一倍的时间片,则剩余运行时间除以时间片长度<1

                {

                    temp=temp+tasks[i].runtime;

                    tasks[i].finishtime=temp;

                    tasks[i].runflag=1;//标记该进程已经运行完毕

                    tasks[i].runtime=copy_task[i].runtime;

                }

            }

        }

    }

return 0;

}

2.6程序流程图

 操作系统实习报告

 

 


2.7测试数据或截图

 操作系统实习报告

 

二、磁盘调度管理

1. 题目内容

设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。

2. 题目要求

1. 最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的

道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。

2.扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。

3.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。

3.设计思想

该算法用vvector标准模板库模拟有许多扇区的磁盘,用srand()和rand()函数随机生成磁盘序列,存放到outfile文件流里面,设计一个选择函数,用switch选择需要调用的SSTF、SCAN、CSCAN算法,也用switch选择是否结束进程。

4.算法分析

4.1程序结构

随机生成序列函数,用srand和rand随机生成序列

void request(vector<int>&m_vec,ofstream &outfile){  

    cout<<"随机生成磁盘序列:"<<endl;  

    int n = 0;  

    srand(time(NULL));    

    n = rand() % 20 + 1; //rand()是一个产生随机数的函数,与srand一起 用,rand()%20+1:n的取值为1-20

    int temp = 0;  

    for(int i=0;i<n;i++){  

        temp = rand() % 100; //temp的取值为0-100

        m_vec.push_back(temp); // 将随机生成的temp数输入到vector里面

        cout<<temp<<" ";  

        outfile<<temp<<endl; //outfile输出数据文件流,输出到输出文件中

    }  

    cout<<endl;  

    position = rand() % 100; //当前磁道为随机生成的0-100之间的数

    cout<<"当前磁道:"<<position<<endl;  

}

②最短寻道算法:

void SSTF(vector<int>m_vec,int position){    

    dis = 0;  

    average_distance = 0;  

    sort(m_vec.begin(),m_vec.end());    //从小到大排序

    int i = 0;  

    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){  

        if(position >= *it) //找到position所在磁道

            i++;  

    }  

    int count = 0;  

    int left = i-1; //i为下标

    int right = i;  

    while(count<m_vec.size()){  //选择扫描方向,如果

        if((left >=0 && abs(m_vec[right]-position) > abs(m_vec[left]-position)) || right>=m_vec.size()){

            dis += abs(m_vec[left]-position);  

            Sleep(500);  

            cout<<"->"<<m_vec[left];  

            position = m_vec[left];  

            left--;  

        }  

        else{ //选择从右边开始扫描

            dis += abs(m_vec[right]-position);  

            Sleep(500);  

            cout<<"->"<<m_vec[right];  

            position = m_vec[right];  

            right++;  

        }  

        count++;  

    }  

    compute_dis(m_vec,dis,average_distance);  

}

③扫描算法:

void SCAN(vector<int>m_vec,int position){    

    dis = 0;  

    average_distance = 0;  

    sort(m_vec.begin(),m_vec.end());    //从小到大排序  

    int i = 0;  

    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){  

        if(position >= *it)  

            i++;      //找到position所在的磁道  

    }  

    int left = i - 1;   //先从外到内扫描  

    int right = i;  

    while(left >= 0){  

        dis += abs(position - m_vec[left]);  

        Sleep(500);  

        cout<<"->"<<m_vec[left];  

        position = m_vec[left];  

        left --;//当左边的序列走完之后跳出这个while循环  

    }  

    while(right < m_vec.size()){  

        dis += abs(position - m_vec[right]);  

        Sleep(500);  

        cout<<"->"<<m_vec[right];  

        position = m_vec[right];  

        right ++;  

    }  

    compute_dis(m_vec,dis,average_distance);  

}

④循环扫描算法:

void CSCAN(vector<int>m_vec,int position){   //循环扫描算法  

    dis = 0;  

    average_distance = 0;  

    sort(m_vec.begin(),m_vec.end());    //从小到大排序  

    int i = 0;  

    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){  

        if(position >= *it)  

            i++;      //找到position所在的磁道  

    }  

    int left = i - 1;   //先从外到内扫描  

    int right = i;  

    while(left >= 0){  

        dis += abs(position - m_vec[left]);  

        Sleep(500);  

        cout<<"->"<<m_vec[left];  

        position = m_vec[left];  

        left --;  

    }  

 

    int len = m_vec.size()-1;  

    while(len >= right){ //从最外侧在是扫描一遍,像梳头发一样

        dis += abs(position - m_vec[len]);

        Sleep(500);  

        cout<<"->"<<m_vec[len];  

        position = m_vec[len];  

        len --;  

    }  

    compute_dis(m_vec,dis,average_distance);  

}

⑤计算平均距离算法:

void compute_dis(vector<int>m_vec,int &dis,double &average_distance){  

    average_distance = (double)dis / (double)m_vec.size();  

}

5.核心代码

int choose_algorithm(vector<int>m_vec){  

    cout<<endl<<endl;  

    cout<<"本实验可用的调度算法有以下3种:"<<endl;  

    cout<<"1.SSTF  2.SCAN  3.CSCAN   4.结束本序列的调度  5.结束程序"<<endl;  

    int choice = 0;  

    cout<<"选择:"<<endl;  

    cin>>choice;  

    cout<<endl;  

    while(choice!=4 && choice!=5){  

        cout<<"磁盘请求的服务状况:"<<endl;  

        cout<<position;  

        switch(choice){  

            case 1:  

                SSTF(m_vec,position);break;  

            case 2:  

                SCAN(m_vec,position);break;  

            case 3:  

                CSCAN(m_vec,position);break;  

 

            default:  

                cout<<"******非法输入!******"<<endl<<endl;break;   

        }   

        if(choice<=5 && choice>=1)   

            print();  

        cout<<"选择:"<<endl;  

        cin>>choice;  

    }  

    if(choice == 5)  

        return 0;  

    else  

        cout<<endl<<endl; //清空输出缓冲区,相当于将vertor初始化

return 1;  

}

6.程序流程图

 操作系统实习报告

7.测试数据或截图

 操作系统实习报告

 

三、心得体会

每一次课程设计度让我学到了在平时课堂不可能学到的东西。不一定我的课程设计能够完成得有多么完美,但是我总是很投入的去研究去学习。但是每完成一个任务我都兴奋不已。总体而言我的课设算是达到了老师的基本要求。总结一下有以下体会。

1、网络真的很强大,用在学习上将是一个非常高效的助手。几乎所有的资料都能够在网上找到。也因为这样,整个课程设计下来,我浏览的相关网页已经超过了100个(不完全统计)。当然网上的东西很乱很杂,自己要能够学会筛选。

2、同学间的讨论,这是很重要的。老师毕竟比较忙。对于课程设计最大的讨论伴侣应该是同学了。能和学长学姐讨论当然再好不过了,没有这个机会的话,和自己班上同学讨论也是能够受益匪浅的。大家都在研究同样的问题,讨论起来,更能够把思路理清楚,相互帮助,可以大大提高效率。

3、敢于攻坚,越是难的问题,越是要有挑战的心理。这样就能够达到废寝忘食的境界。当然这也是不提倡熬夜的,毕竟有了精力才能够打持久战。但是做课设一定要有状态,能够在吃饭,睡觉,上厕所都想着要解决的问题,这样你不成功都难。