操作系统:实验四进程调度实验

news2024/11/15 20:11:29

一、实验目的

1、了解操作系统CPU管理的主要内容。

2、加深理解操作系统管理控制进程的数据结构--PCB。

3、掌握几种常见的CPU调度算法(FCFS、SJF、HRRF、RR)的基本思想和实现过程。

4、用C语言模拟实现CPU调度算法。

5、掌握CPU调度算法性能评价指标的计算方法。

6、通过对进程调度算法的模拟加深对进程概念和进程调度算法的理解。

、实验内容

1、用C语言编写程序,模拟单处理器下先来先服务算法FCFS,要求显示各进程的到达时间、服务时间、完成时间,周转时间以及该算法的平均周转时间和平均带权周转时间。运行以下参考程序,给出结果截图并分析该算法的优缺点。(3分)

参考程序:

#include <stdio.h>

#include <stdlib.h>

struct PCB   //先来先服务FCFS

{

    char name[10];     //进程名

    float arrivetime;   //到达时间

    float servetime;    //服务时间

    float finishtime;   //完成时间

    float roundtime;    //周转时间

    float daiquantime;  //带权周转时间

};

struct PCB a[50];//定义进程数组

struct PCB *sortarrivetime(struct PCB a[], int n);//声明到达时间冒泡排序函数

void FCFS(struct PCB a[],int n,float *t1,float *t2);//先来先服务算法



//按到达时间进行冒泡排序

struct PCB *sortarrivetime(struct PCB a[], int n){

    int i, j;

    struct PCB t;

    int flag;      //标志变量,记录在每一趟冒泡中是否有元素交换,没有交换则结束冒泡

    for (i = 1; i<n; i++)   //外层循环控制比较趟数

    {

        flag = 0;   //初始值设置为0

        for (j = 0; j<n - i; j++)   //内存循环控制每一趟的比较次数

        {

           if (a[j].arrivetime>a[j + 1].arrivetime)    //将到达时间短的交换到前边

           {

               t = a[j];

               a[j] = a[j + 1];

               a[j + 1] = t;

               flag = 1;       //有交换,flag置1

           }

        }

        if (flag == 0)//如果一趟排序中没发生任何交换,则排序结束   

        {

           break;

        }

    }

    return a;   //返回排序后进程数组

}



//先来先服务算法

void FCFS(struct PCB a[],int n,float *t1,float *t2)

{

    int i;

    a[0].finishtime = a[0].arrivetime + a[0].servetime; //完成时间=到达时间+服务时间

    a[0].roundtime = a[0].finishtime - a[0].arrivetime; //周转时间=完成时间-到达时间

    a[0].daiquantime = a[0].roundtime / a[0].servetime; //带权时间=周转时间/服务时间

    for (i = 1; i<n; i++)

    {

       if (a[i].arrivetime<a[i-1].finishtime)//当前到达时间在上一个作业结束时间之前

       {

        a[i].finishtime = a[i-1].finishtime + a[i].servetime;//完成时间=上一个完成时间+服务时间

        a[i].roundtime = a[i].finishtime - a[i].arrivetime; //周转时间=完成时间-到达时间

        a[i].daiquantime = a[i].roundtime / a[i].servetime; //带权时间=周转时间/服务时间

        }

        else    //当前到达时间在上一个作业结束时间之后

        {

           a[i].finishtime = a[i].arrivetime + a[i].servetime;//完成时间=到达时间+服务时间

           a[i].roundtime = a[i].finishtime - a[i].arrivetime;    //周转时间=完成时间-到达时间

           a[i].daiquantime = a[i].roundtime / a[i].servetime;//带权时间=周转时间/服务时间

        }

    }

    printf("=============================================================\n");

        printf("进程相关信息如下:\n\n");

        printf("进程名    ");

        printf("到达时间  ");

        printf("服务时间  ");

        printf("完成时间  ");

        printf("周转时间  ");

        printf("带权周转时间\n");

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

        {

           printf("%-10s",a[i].name);

           printf("%-10.0f",a[i].arrivetime);

           printf("%-10.0f",a[i].servetime);

           printf("%-10.0f",a[i].finishtime);

           printf("%-10.0f",a[i].roundtime);

           printf("%10.2f\n",a[i].daiquantime);

           *t1 += a[i].roundtime; 

           *t2 += a[i].daiquantime;

        }

   

}

int main()

{

    float t1 ;  //总周转时间

    float t2 ;  //总带权周转时间

    float avr_t1 ;  //平均周转时间

    float avr_t2 ;  //平均带权周转时间

    int n, i;

    char select = ' ';  //选择算法变量标识

    while (select != '2')   //不为退出标识,保持循环

    {  

        t1 = 0.0f; 

        t2 = 0.0f;     

        system("clear");

        printf("\n请选择算法:1.先来先服务算法  2.退出程序\n\n请输入选择:  ");

        scanf("%c", &select);  

        if (select == '1')  //先来先服务算法

        {

           printf("\n=====================先来先服务算法FCFS=====================\n\n");

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

           scanf("%d", &n);

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

           {

               printf("%d 进程名:", i + 1);

               scanf("%s", a[i].name);

               printf("到达时间:");

               scanf("%f", &a[i].arrivetime);

               printf("服务时间:");

               scanf("%f", &a[i].servetime);

           }

           getchar();

           sortarrivetime(a, n);//按到达时间先后进行冒泡排序

           FCFS(a,n,&t1,&t2);  //先来先服务算法

           avr_t1 = t1 / n;

           avr_t2 = t2 / n;

           printf("\n");

           printf("平均周转时间为:%2.2f\n", avr_t1);

           printf("平均带权周转时间为:%2.2f\n", avr_t2);

           getchar();

        }

        else if (select == '2')

        {

           exit(0);

        }

        else

        {

           printf("please enter right choose!\n");

        }

    }

    return 0;

}

请同学按下列给出的数据测试运行结果:

进程

到达时间

服务时间

P1

0

4

P2

1

6

P3

2

3

P4

3

1

P5

7

2

要求给出编译及运行过程和运行结果:

分析该算法优缺点:

先来先服务 (FCFS) 算法是一种简单的调度算法,它按照作业到达的先后顺序进行调度,先到达的作业先得到执行。

优点:

  1. 简单直观: FCFS 算法是最简单、最直观的调度算法之一,易于实现和理解。
  2. 无饥饿现象: 由于按照到达顺序执行,不存在某些作业长时间等待而无法执行的情况,避免了饥饿现象。

缺点:

  1. 平均等待时间不稳定: FCFS 算法可能导致平均等待时间较长,特别是当某个长服务时间的作业先到达时,后续作业需要等待较长时间。
  2. 不适合短作业: 对于长作业和短作业混合的情况,FCFS 可能会导致短作业长时间等待,影响系统的响应时间和效率。
  3. 无法充分利用 CPU: FCFS 算法不考虑作业的执行时间长短,可能导致 CPU 的利用率较低。

综上所述,FCFS 算法适用于作业长度差异不大且不需要考虑作业执行时间的情况,但对于需要提高系统响应时间和利用率的情况,更复杂的调度算法如短作业优先 (SJF)、优先级调度、多级反馈队列等可能更加合适。

2.编程实现最短作业优先算法 SJF。(3分)

参考程序框架:

#include <stdio.h>

#include <stdlib.h>

struct PCB

{

    char name[10];     //进程名

    float arrivetime;   //到达时间

    float servetime;    //服务时间

    float finishtime;   //完成时间

    float roundtime;    //周转时间

    float daiquantime;  //带权周转时间

};

struct PCB a[50];//初始化指针和数组

struct PCB *sortarrivetime(struct PCB a[], int n);//声明到达时间冒泡排序函数

void SJF(struct PCB a[], int n, float *t1, float *t2);//声明短作业优先算法函数

struct PCB *sortarrivetime(struct PCB a[], int n)

{   int i, j;

    struct PCB t;

    int flag;      //标志变量,记录在每一趟冒泡中是否有元素交换,没有交换则结束冒泡

    for (i = 1; i<n; i++)   //外层循环控制比较趟数

    {

        flag = 0;   //初始值设置为0

        for (j = 0; j<n - i; j++)   //内存循环控制每一趟的比较次数

        {

           if (a[j].arrivetime>a[j + 1].arrivetime)    //将到达时间短的交换到前边

           {

               t = a[j];

               a[j] = a[j + 1];

               a[j + 1] = t;

               flag = 1;       //有交换,flag置1

           }

        }

        if (flag == 0)//如果一趟排序中没发生任何交换,则排序结束   

        {

           break;

        }

    }

    return a;   //返回排序后进程数组

}

//短作业优先算法

void SJF(struct PCB a[], int n, float *t1, float *t2)

{

    int i,c,d;

    struct PCB t;

    a[0].finishtime = a[0].arrivetime + a[0].servetime; //完成时间=到达时间+服务时间

    a[0].roundtime = a[0].finishtime - a[0].arrivetime; //周转时间=完成时间-提交时间

    a[0].daiquantime = a[0].roundtime / a[0].servetime; //带权时间=周转时间/服务时间

    for (i = 1; i < n; i++)

    {

        for (c = i; c < n - 1; c++)

        {

           for (d=c+1;d<n;d++)     //d=i+1改成d=c+1

           if ((a[i - 1].finishtime >= a[c].arrivetime)&&(a[i - 1].finishtime >= a[d].arrivetime) && (a[c].servetime > a[d].servetime))

           {

               t = a[c];

               a[c] = a[d];

               a[d] = t;

           }

         }

        if (a[i].arrivetime<a[i - 1].finishtime)    //当前到达时间在上一个作业结束时间之前

        {

          

a[i].finishtime = a[i - 1].finishtime + a[i].servetime; 

        }

        else    //当前到达时间在上一个作业结束时间之后

        {

          

a[i].finishtime = a[i].arrivetime + a[i].servetime;              

        }

    }

    printf("=============================================================\n");

        printf("进程相关信息如下:\n\n");

        printf("进程名    ");

        printf("到达时间  ");

        printf("服务时间  ");

        printf("完成时间  ");

        printf("周转时间  ");

        printf("带权周转时间\n");

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

        {

           printf("%-10s",a[i].name);

           printf("%-10.0f",a[i].arrivetime);

           printf("%-10.0f",a[i].servetime);

           printf("%-10.0f",a[i].finishtime);

           printf("%-10.0f",a[i].roundtime);

           printf("%10.2f\n",a[i].daiquantime);

           *t1 += a[i].roundtime;

           *t2 += a[i].daiquantime;

        }  

}

int main()

{

    float t1 ;  //总周转时间

    float t2 ;  //总带权周转时间

    float avr_t1 ;  //平均周转时间

    float avr_t2 ;  //平均带权周转时间

    int n, i;

    char select = ' ';  //选择算法变量标识

    while (select != '2')   //不为退出标识,保持循环

    {  

        t1 = 0.0f; 

        t2 = 0.0f;     

        system("clear");

        printf("请选择算法:1.短作业优先算法  2.退出程序\n\n请输入选择:  ");

        scanf("%c", &select);  

        if (select == '1')  //短作业优先算法

        {

           printf("\n=====================短作业优先算法SJF=====================\n\n");

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

           scanf("%d", &n);

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

           {

               printf("%d 进程名:", i + 1);

               scanf("%s", a[i].name);

               printf("到达时间:");

               scanf("%f", &a[i].arrivetime);

               printf("服务时间:");

               scanf("%f", &a[i].servetime);

           }

            getchar();

           sortArrivalTime(a, n);  //按到达时间进行冒泡排序

           SJF(a, n, &t1, &t2);   //调短作业优先算法

           avr_t1=t1/n //平均周转时间

            avr_t2=t2/n //平均带权周转时间

           printf("\n");

           printf("平均周转时间为:%2.2f \n", avr_t1);

           printf("平均带权周转时间为:%2.2f \n", avr_t2);

           getchar();

        }

        else if (select == '2')

        {

           exit(0);

        }

        else

{

           printf("please enter right choose!\n");

           getchar();

        }

    }

    return 0;

}

编译及执行过程以及结果截屏:

分析该算法的优缺点:

短作业优先 (Shortest Job First, SJF) 算法是一种基于作业服务时间长度的调度算法。它会优先选择服务时间最短的作业来执行,以最小化平均等待时间和周转时间。

优点:

1. 最小化平均等待时间: SJF 算法能够在所有就绪作业中优先执行服务时间最短的作业,从而使平均等待时间最小化。

2. 最小化周转时间: 由于短作业先执行,因此整体作业完成时间相对较短,周转时间较小。

3. 高效利用 CPU: SJF 算法能够有效利用 CPU 资源,优先处理短作业,从而提高系统的响应速度和效率。

4. 避免长作业等待: SJF 算法能够避免长作业长时间占用 CPU 而导致其他作业等待过久的情况,降低了长作业对系统性能的影响。

缺点:

1. 无法预测作业的准确服务时间: SJF 算法要求预先知道每个作业的准确服务时间,但实际情况下很难预测作业的执行时间。

2. 可能导致长作业饥饿: 如果一些长服务时间的作业不断被短作业抢占 CPU 资源,长作业可能长时间等待,出现饥饿现象。

3. 可能引入优先级反转问题: 当有一个短作业不断到达并抢占 CPU,长作业需要等待,可能导致长作业优先级反转的问题。

4. 对响应时间不敏感: SJF 算法更注重长期的平均等待时间和周转时间,而对单个作业的响应时间不敏感,可能导致一些作业等待时间较长。

综上所述,SJF 算法在作业长度相差较大且服务时间可预测的情况下效果较好,但实际应用中需要注意预测服务时间的准确性、长作业饥饿的问题以及对响应时间的敏感度。针对不同的应用场景和系统需求,需要综合考虑 SJF 算法的优缺点,选择合适的调度算法来优化系统性能。

3.编程实现最高响应比优先算法HRN,并分析该算法的优缺点。(要求给出程序设计分析和调试通过的程序,并给出编译,运行步骤和执行结果截图。)(3分)

#include <stdio.h>

#include <stdlib.h>

struct PCB

{

    char name[10];     //进程名

    float arrivetime;   //到达时间

    float servetime;    //服务时间

    float finishtime;   //完成时间

    float roundtime;    //周转时间

    float daiquantime;  //带权周转时间

};

struct PCB a[50];//初始化指针和数组

struct PCB *sortarrivetime(struct PCB a[], int n);//声明到达时间冒泡排序函数

void SJF(struct PCB a[], int n, float *t1, float *t2);//声明短作业优先算法函数

struct PCB *sortarrivetime(struct PCB a[], int n)

{   int i, j;

    struct PCB t;

    int flag;      //标志变量,记录在每一趟冒泡中是否有元素交换,没有交换则结束冒泡

    for (i = 1; i<n; i++)   //外层循环控制比较趟数

    {

        flag = 0;   //初始值设置为0

        for (j = 0; j<n - i; j++)   //内存循环控制每一趟的比较次数

        {

           if (a[j].arrivetime>a[j + 1].arrivetime)    //将到达时间短的交换到前边

           {

               t = a[j];

               a[j] = a[j + 1];

               a[j + 1] = t;

               flag = 1;       //有交换,flag置1

           }

        }

        if (flag == 0)//如果一趟排序中没发生任何交换,则排序结束   

        {

           break;

        }

    }

    return a;   //返回排序后进程数组

}





void HRN(struct PCB a[], int n, float *t1, float *t2)

{

    int i, j;

    struct PCB t;



    // 初始化第一个进程的完成时间、周转时间和带权周转时间

    a[0].finishtime = a[0].arrivetime + a[0].servetime;

    a[0].roundtime = a[0].finishtime - a[0].arrivetime;

    a[0].daiquantime = a[0].roundtime / a[0].servetime;



    for (i = 1; i < n; i++)

    {

        // 计算每个进程的响应比率并选择响应比率最高的进程进行执行

        float max_ratio = -1.0f;

        int max_index = -1;



        for (j = i; j < n; j++)

        {

            // 检查进程是否在上一个进程完成后到达

            if (a[j].arrivetime <= a[i - 1].finishtime)

            {

                // 计算响应比率:(等待时间 + 服务时间) / 服务时间

                float ratio = (a[i - 1].finishtime - a[j].arrivetime + a[j].servetime) / a[j].servetime;



                // 更新最高响应比率和对应的进程索引

                if (ratio > max_ratio)

                {

                    max_ratio = ratio;

                    max_index = j;

                }

            }

        }



        // 将具有最高响应比率的进程与当前位置进行交换

        if (max_index != -1)

        {

            t = a[i];

            a[i] = a[max_index];

            a[max_index] = t;

        }



        // 更新当前进程的完成时间、周转时间和带权周转时间

        a[i].finishtime = a[i - 1].finishtime + a[i].servetime;

        a[i].roundtime = a[i].finishtime - a[i].arrivetime;

        a[i].daiquantime = a[i].roundtime / a[i].servetime;

    }



    // 输出进程信息

    printf("=============================================================\n");

    printf("进程相关信息如下:\n\n");

    printf("进程名    ");

    printf("到达时间  ");

    printf("服务时间  ");

    printf("完成时间  ");

    printf("周转时间  ");

    printf("带权周转时间\n");

   

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

    {

        printf("%-10s", a[i].name);

        printf("%-10.0f", a[i].arrivetime);

        printf("%-10.0f", a[i].servetime);

        printf("%-10.0f", a[i].finishtime);

        printf("%-10.0f", a[i].roundtime);

        printf("%10.2f\n", a[i].daiquantime);



        // 累加总周转时间和总带权周转时间

        *t1 += a[i].roundtime;

        *t2 += a[i].daiquantime;

    }

}





int main()

{

    float t1 ;  //总周转时间

    float t2 ;  //总带权周转时间

    float avr_t1 ;  //平均周转时间

    float avr_t2 ;  //平均带权周转时间

    int n, i;

    char select = ' ';  //选择算法变量标识

    while (select != '2')   //不为退出标识,保持循环

    {  

        t1 = 0.0f; 

        t2 = 0.0f;     

        system("clear");

        printf("请选择算法:1. 最高响应比优先算法  2.退出程序\n\n请输入选择:  ");

        scanf("%c", &select);  

        if (select == '1')  //最高响应比优先算法

        {

           printf("\n=====================最高响应比优先算法SJF=====================\n\n");

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

           scanf("%d", &n);

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

           {

               printf("%d 进程名:", i + 1);

               scanf("%s", a[i].name);

               printf("到达时间:");

               scanf("%f", &a[i].arrivetime);

               printf("服务时间:");

               scanf("%f", &a[i].servetime);

           }

            getchar();

           sortarrivetime(a, n);   //按到达时间进行冒泡排序

           HRN(a, n, &t1, &t2); 

           avr_t1=t1/n;    //平均周转时间

            avr_t2=t2/n;    //平均带权周转时间

           printf("\n");

           printf("平均周转时间为:%2.2f \n", avr_t1);

           printf("平均带权周转时间为:%2.2f \n", avr_t2);

           getchar();

        }

        else if (select == '2')

        {

           exit(0);

        }

        else

{

           printf("please enter right choose!\n");

           getchar();

        }

    }

    return 0;

}

最高响应比优先算法(Highest Response Ratio Next, HRN)是一种作业调度算法,它根据作业的等待时间和服务时间来选择下一个执行的作业。

优点:

  1. 考虑作业的等待时间和服务时间: HRN 算法综合考虑作业的等待时间和服务时间,通过计算响应比率来决定作业的执行顺序,更能够反映作业的紧迫程度和优先级。
  2. 公平性较高: HRN 算法倾向于优先执行等待时间较长且服务时间较短的作业,从而提高作业的响应速度和整体性能,更加公平地分配 CPU 资源。
  3. 能够避免长作业饥饿: 类似于短作业优先算法,HRN 算法也能够避免长作业长时间等待,优先执行等待时间较短的作业,降低长作业饥饿的可能性。

缺点:

  1. 计算复杂度较高: HRN 算法需要计算每个作业的响应比率,涉及除法运算,因此算法的计算复杂度较高,特别是当作业数量较大时。
  2. 可能出现优先级反转问题: 如果某个长作业长时间等待,但在短作业到达后仍然没有得到执行,可能导致长作业的优先级被降低,出现优先级反转问题。
  3. 对服务时间的依赖性: HRN 算法对于作业的服务时间要求相对严格,需要较准确地预测每个作业的服务时间,否则可能导致算法效果不佳。

综上所述,HRN 算法在一定程度上能够提高作业的响应速度和系统的整体性能,但需要注意计算复杂度较高和对作业服务时间的依赖性。在实际应用中,需要根据具体场景和需求,权衡 HRN 算法的优点和缺点,选择合适的调度算法来优化系统性能。

4、编程实现时间片轮换算法,并分析算法的优缺点。(要求给出程序设计分析和调试通过的程序,并给出编译,运行步骤和执行结果截图。)(附加题)

#include <stdio.h>

#include <stdlib.h>



struct Process {

    char name[10];      // 进程名

    float arrival_time; // 到达时间

    float service_time; // 服务时间

    float remaining_time; // 剩余服务时间

    float turnaround_time; // 周转时间

    float weighted_turnaround_time; // 带权周转时间

};



// 时间片轮转调度算法实现

void roundRobin(struct Process processes[], int n, float time_slice) {

    int completed_processes = 0;

    float current_time = 0;

   

    while (completed_processes < n) {

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

            if (processes[i].remaining_time > 0) {

                // 执行当前进程直至时间片用完或进程执行完毕

                if (processes[i].remaining_time <= time_slice) {

                    // 进程执行完毕

                    current_time += processes[i].remaining_time;

                    processes[i].remaining_time = 0;

                    completed_processes++;

                   

                    // 计算周转时间和带权周转时间

                    processes[i].turnaround_time = current_time - processes[i].arrival_time;

                    processes[i].weighted_turnaround_time = processes[i].turnaround_time / processes[i].service_time;

                } else {

                    // 时间片用完

                    current_time += time_slice;

                    processes[i].remaining_time -= time_slice;

                }

            }

        }

    }

}



int main() {

    int n;

    float time_slice;



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

    scanf("%d", &n);



    struct Process processes[n];



    // 输入进程信息

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

        printf("进程名:");

        scanf("%s", processes[i].name);

        printf("到达时间:");

        scanf("%f", &processes[i].arrival_time);

        printf("服务时间:");

        scanf("%f", &processes[i].service_time);



        // 初始化剩余服务时间

        processes[i].remaining_time = processes[i].service_time;

        processes[i].turnaround_time = 0;

        processes[i].weighted_turnaround_time = 0;

    }



    printf("请输入时间片大小:");

    scanf("%f", &time_slice);



    // 执行时间片轮转调度算法

    roundRobin(processes, n, time_slice);



    // 输出结果

    printf("\n进程名\t到达时间\t服务时间\t周转时间\t带权周转时间\n");

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

        printf("%s\t%.1f\t\t%.1f\t\t%.1f\t\t%.2f\n",

               processes[i].name, processes[i].arrival_time,

               processes[i].service_time, processes[i].turnaround_time,

               processes[i].weighted_turnaround_time);

    }



    return 0;

}

优点:

公平性: 时间片轮换算法保证了每个进程都能在一定时间内得到执行,避免了长时间等待的情况,因此具有较好的公平性。

简单易实现: 时间片轮换算法的实现相对简单直观,主要涉及将 CPU 时间划分为固定大小的时间片,并按顺序轮流执行进程。

响应时间较短: 对于需要快速响应的系统,时间片轮换算法能够保证每个进程都有机会在相对短的时间内执行一定量的任务,从而提高了系统的响应速度。

缺点:

低效性: 时间片轮换算法可能导致一定程度上的性能下降,特别是当时间片设置过小时,会增加进程上下文切换的频率,增加系统开销。

不适用于长作业: 对于长时间运行的作业,时间片轮换算法可能会导致频繁的上下文切换,影响系统的整体性能,而且长作业在等待执行时可能需要等待较长时间。

无法适应实时性要求: 时间片轮换算法无法有效应对对实时性要求较高的系统,因为它无法保证进程能够在规定的时间内完成任务。

平均等待时间较长: 如果时间片设置过大,会导致短作业也需要等待较长时间才能得到执行,从而增加了平均等待时间。

对系统负载敏感: 时间片轮换算法的效率很大程度上取决于时间片的大小和系统负载,需要合理调整时间片大小才能达到较好的性能表现。

三、实验总结和体会(1分)

通过本次实验,我学到了以下几点:

  1. 进程调度算法的实现:实际编写了几种常见的进程调度算法,包括短作业优先(SJF)算法和时间片轮转调度算法。这些算法是操作系统中重要的组成部分,用于决定进程如何在 CPU 上执行,从而影响系统的性能和响应速度。
  2. 算法的工作原理:深入理解了不同进程调度算法的工作原理和特点。例如,SJF算法通过选择服务时间最短的进程来优先执行,而时间片轮转调度算法则通过固定大小的时间片轮流执行进程,实现了一种公平的调度方式。
  3. 算法的优缺点:通过分析每种算法的优缺点,我意识到不同的调度算法适用于不同的场景。例如,SJF算法对短作业有较好的响应,但可能导致长作业等待过久;时间片轮转调度算法能够避免长作业等待,但可能引入较多的上下文切换。
  4. 编程技能的提升:通过实践编程,我加深了对 C 语言的理解和应用,掌握了结构体、函数、循环等编程基础知识。同时,我学会了如何组织和设计一个完整的进程调度程序,包括输入处理、算法实现和结果输出。
  5. 实践中的挑战和解决方案:在编写代码的过程中,遇到了一些挑战,如算法逻辑的设计和调试过程中的错误。通过分析问题、调试代码和查阅资料,我逐步解决了这些问题,提升了解决实际问题的能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2089747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于python文案转语音并输出-自媒体等职业副业均可使用,不受他人限制

开发背景: 目前自媒体比较火爆,有很多书单、视频等推广方式可以作为副业盈利,之前每次搞的时候都需要不停的网上找一些在线文字转语音的平台将文案复制上去然后生成下载,好多还是付费的,挺无奈的,然后就想着自己能不能搞,然后的然后就有了下面的东西, 如果大家有此类需要…

文心智能体-梦想目标实现助手-实现你的老板梦

前言&#xff1a; 其实我从小就很羡慕小说里面的男主&#xff0c;从家境贫寒到后面成为天之骄子&#xff0c;在一路上都有很多好的机遇和贵人。用今天的话来说&#xff0c;男主好像都有一个“系统”&#xff0c;毫不意外&#xff0c;我也有这样的武侠梦&#xff0c;金庸的小说更…

波导阵列天线学习笔记6 用于K和Ka频段卫星通信的超宽带双圆极化波导阵列天线

摘要: 在本文中&#xff0c;设计了一种用于K和Ka双频段的宽带双圆极化波导天线阵列。一种多级方波导结构被利用&#xff08;exploited&#xff09;在辐射层内来实现双极化响应的激励。一种脊波导极化器被集成在内来实现左旋圆极化和右旋圆极化。为了馈网的更好设计&#xff0c;…

qtlinux

filezilla传 白色 权限不够 chmod x ./运行 source路径 qmake make 55可执行文件 nfs拷贝到开发版 ./运行 make j 核数 &#xff08;加速编译过程&#xff09;

【精选】推荐4款写作效率翻倍的AI论文写作助手

在当前的学术研究和写作领域&#xff0c;AI论文写作助手已经成为提高写作效率和质量的重要工具。这些工具利用先进的自然语言处理和机器学习技术&#xff0c;帮助研究人员和学生快速生成论文草稿、优化内容、进行查重和排版等操作。以下是四款高效且广受好评的AI论文写作助手&a…

迎来“成人礼”的良品铺子,蜕变了吗?

成立18年的良品铺子&#xff0c;正在迎来一场“成人礼”。 在这一关键节点&#xff0c;“苦”可能是其最先品尝到的味道。据良品铺子近日发布的财报&#xff0c;2024年上半年&#xff0c;公司实现营业收入38.86亿元&#xff0c;同比下滑2.52%&#xff1b;归属于上市公司股东的…

python脚本如何用sleep

Python 编程中使用 time 模块可以让程序休眠&#xff0c;具体方法是time.sleep(秒数)&#xff0c;其中“秒数”以秒为单位&#xff0c;可以是小数&#xff0c;0.1秒则代表休眠100毫秒。 代码如下&#xff1a; # 例1&#xff1a;循环输出休眠1秒 import time i 1 while i <…

Linux Debian12安装flameshot火焰截图工具

一、Linux Debian12安装flameshot 打开终端&#xff0c;运行&#xff1a; sudo apt install flameshot安装成功后&#xff0c;使用下面命令查看帮助信息&#xff1a; flameshot -h其中flameshot launcher命令可以打开启动器。 二、使用flameshot截图方法 打开终端&#x…

记录使用DevExpress的过程遇到问题

vs 2022 版本 DevExpress 版本 24.1 先参考这个网站去下载DevExpress和PatchDevExpress 24.1 版本使用 barManager1 使用过程&#xff1a; 1.菜单栏 默认经典样式 &#xff1a; 1.1 添加下拉菜单&#xff1a; 按照自己的需求去添加 如果有选择 barCheckItem1 复选框的控…

关于欧洲玩家的几个事实

欧洲游戏玩家是一个多元化和复杂的受众&#xff0c;受到广泛的文化、语言和社会因素的影响。他们的游戏偏好和行为在整个欧洲大陆上差异很大&#xff0c;反映了定义欧洲的丰富的民族认同和地区差异。 欧洲游戏玩家最显著的特征之一是他们对本地化内容的偏好。仅在欧盟就有二十…

5分钟部署Prometheus+Grafana批量监控Linux服务器

文章目录 一键安装Node Exporter安装prometheus创建数据存储目录创建配置文件下载运行Prometheus 安装Grafana创建数据目录下载运行Grafana配置Grafana监控Linux服务器登录首次登录后设置密码添加数据源选择prometheus填写prometheus地址导入模板 最近开始公众号文章也开始同步…

ArcGIS Pro技术应用

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

IT/研发团队的秘密武器:9款协作工具盘点

本文将介绍的9款工具如下&#xff1a;1.Worktile&#xff1b;2.PingCode&#xff1b;3.企业微信&#xff1b;4.WPS协作&#xff1b;5.融洽&#xff1b;6.印象团队&#xff1b;7.ClickUp&#xff1b;8.Redbooth&#xff1b;9.Podio。 在管理IT或研发团队时&#xff0c;选择合适的…

kube-scheduler调度任务的执行过程分析与源码解读(二)

概述 摘要&#xff1a; 上文我们对Kube-scheduler的启动流程进行了分析&#xff0c;本文继续探究kube-scheduler执行pod的调度任务的过程。 正文 说明&#xff1a;基于 kubernetes v1.12.0 源码分析 上文讲到kube-scheduler组件通过sched.Run() 启动调度器实例。在sched.Run(…

贵州大数据实验室建设案例分享

贵州大数据实验室建设与学科建设紧密结合&#xff0c;旨在为高校提供教学资源和实训环境&#xff0c;以支持大数据技术人才的培养。高校在实验室规划过程中&#xff0c;第一要务就是从学科定位出发、结合学校的特色和行业优势&#xff0c;定义人才培养目标和方向&#xff0c;并…

栈——有效的括号

在这道题中给出一个字符串包含三种不同的括号&#xff0c;需要判断这三个括号是否能相互匹配。因为方向需要保证不出错&#xff0c;所以我们可以想到如果指向字符的指针为左括号时&#xff0c;可以将它拿出&#xff0c;与下一个字符进行匹配若能匹配则继续匹配&#xff0c;如果…

一文搞懂Window、PhoneWindow、DercorView、WindowManage

戳蓝字“牛晓伟”关注我哦&#xff01; 用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章&#xff0c;技术文章也可以有温度。 本文摘要 通过本文您可以了解PhoneWindow&#xff0c;Window&#xff0c;DecorView&#xff0c;WindowManager&#xff0c;WindowManag…

虚拟机【linux】配置无线网络

虚拟机【linux】配置无线网络 在Linux系统中配置网卡是一个常见的任务&#xff0c;特别是当你需要手动设置IP地址、子网掩码、网关或DNS服务器等信息时。不同的Linux发行版可能有不同的配置方法&#xff0c;但以下是一些基本且通用的步骤来配置网卡。 1. 确定网卡名称 首先&…

【云原生】Kubernetes中如何通过Pod名称查询Docker容器ID,通过Docker容器ID查询Pod名称?

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

中秋节不容错过的送礼指南,除了月饼,还有五大科技好物助力团圆

中秋节&#xff0c;作为中华民族的传统节日&#xff0c;承载着深厚的文化内涵和家庭团聚的美好愿望。在这个月圆人圆的时刻&#xff0c;送礼成为了表达情感和祝福的重要方式。虽然月饼作为传统的象征&#xff0c;总是节日礼单上的首选&#xff0c;但随着科技的发展&#xff0c;…