【C语言】【分享】操作系统 时间片轮转模拟

#include<stdio.h>
#define N 50
struct PCB
{
    int pn;   //process name进程名字
    int at;   //arrival time到达时间
    int st;   //service time服务时间
    int ct;   //completion time完成时刻
    int sc;  //sign completion标志是否完成
    int st1;  //剩余服务时间 
}process[N];
 
int sjp(int n)
{
    int i, j, T;
    printf("\n请输入时间片:\n");
    scanf("%d", &T);
    for (i = 1; i <= n; i++)      //收集进程信息
    {
        process[i].sc = 0;
        printf("\n%d:\n请依次输入进程的信息\n请输入pn:", i);
        scanf("%d", &process[i].pn);
        printf("请输入at:");
        scanf("%d", &process[i].at);
        printf("请输入st:");
        scanf("%d", &process[i].st);
        process[i].st1 = process[i].st;
    }
    for (i = 1; i <= n; i++)
        for (j = i + 1; j <= n; j++)   //按照各进程到达时间升序,对进程排序 注意:稳定的排序
        {
            if (process[j].at < process[i].at)
            {
                process[0] = process[j];
                process[j] = process[i];
                process[i] = process[0];
            }
        }
    //for(i=1;i<=n;i++)    //检查排序是否正确
    //printf("%d\t",process[i].pn);
 
    int time = process[1].at;      //当前时间的初值
    int flag = 1;
    int sum = 0;                    //记录完成的进程数
    printf("\n第几次调度进程 运行的进程pn 开始运行时间 运行时间 剩余服务时间 结束时间\n");
    int z = 1;   //记录第几次调度进程
 
    while (sum < n)
    {
        flag = 0;        //标志就绪队列中是否还有进程
        for (i = 1; i <= n; i++)    //时间片轮转法执行各进程
        {
            if (process[i].sc == 1) continue;  //已完成的进程
            else
            {
                if (process[i].st1 <= T && time >= process[i].at)//未完成的进程但是还需服务的时间少于等于一个时间片
                {
                    flag = 1;
                    time = time + process[i].st1;
                    process[i].sc = 1;
                    process[i].ct = time;
                    printf("%8d%12d%15d%11d%11d%11d\n", z++, process[i].pn, time - process[i].st1, process[i].st1, 0, time);
                    process[i].st1 = 0;
                }
 
                else if (process[i].st1 > T&&time >= process[i].at)//未完成的进程但其还需服务时间至少大于一个时间片
                {
                    flag = 1;
                    time = time + T;
                    process[i].st1 -= T;
                    printf("%8d%12d%15d%11d%11d%11d\n", z++, process[i].pn, time - T, T, process[i].st1, time);
                }
                if (process[i].sc == 1) sum++;     //一个进程执行完就+1
            }
        }
 
        if (flag == 0 && sum < n)   // 还有没执行的进程,且没进入就就绪队列
        {
            for (i = 1; i <= n; i++)
                if (process[i].sc == 0) { time = process[i].at; break; }
        }
    }
    return 0;
}
 
int main()
{
    int n;
    printf("\t\t时间片轮转调度算法\n");
    printf("请输入总进程数:\n");
    scanf("%d", &n);
    sjp(n);
    return 0;
}
 
 
/*
 
                时间片轮转调度算法
请输入总进程数:
5
 
请输入时间片:
1
 
1:
请依次输入进程的信息
请输入pn:1
请输入at:0
请输入st:4
 
2:
请依次输入进程的信息
请输入pn:2
请输入at:1
请输入st:3
 
3:
请依次输入进程的信息
请输入pn:3
请输入at:2
请输入st:5
 
4:
请依次输入进程的信息
请输入pn:4
请输入at:3
请输入st:2
 
5:
请依次输入进程的信息
请输入pn:5
请输入at:4
请输入st:4
 
第几次调度进程 运行的进程pn 开始运行时间 运行时间 剩余服务时间 结束时间
       1           1              0          1          3          1
       2           2              1          1          2          2
       3           3              2          1          4          3
       4           4              3          1          1          4
       5           5              4          1          3          5
       6           1              5          1          2          6
       7           2              6          1          1          7
       8           3              7          1          3          8
       9           4              8          1          0          9
      10           5              9          1          2         10
      11           1             10          1          1         11
      12           2             11          1          0         12
      13           3             12          1          2         13
      14           5             13          1          1         14
      15           1             14          1          0         15
      16           3             15          1          1         16
      17           5             16          1          0         17
      18           3             17          1          0         18
*/

代码2

#include<stdio.h>
#define MAX 10
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();//判断是否所有的进程都被执行过
 
 
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())//while条件,charge为0跳出(说明进程都已经全部执行完毕),为1进入(进程还未执行完毕,继续执行)
    {
        for (i = 0; i < counter; i++)
        {
            if (tasks[i].arrivetime > temp)//如果第i个的到达时间大于第一个的到达时间,则将第i个的到达时间与temp交换,更新temp的记录,但是第一次运行的时候不走这一步
            {
                temp = tasks[i].arrivetime;
            }
            if (tasks[i].runflag == 0)//第i个进程还未结束
            {
                if (tasks[i].startflag == 0)  //该条件成立则说明,该进程是第一次执行,记录开始执行时间
                {
                    tasks[i].starttime = temp;//第一个进程的到达时间为temp
                    tasks[i].startflag = 1;//运行完上一步后记录该进程已经不是第一次运行了
                }
                if (tasks[i].runtime / timecounter > 1)//,运行时间除以时间片长度,说明至少有两倍的时间片未执行
                {
                    tasks[i].runtime = tasks[i].runtime - timecounter;//剩余运行时间就等于原来运行时间减去一个时间片长度
                    temp = temp + timecounter;//temp继续记录已用的时间片长度
                }
                else if (tasks[i].runtime - timecounter == 0)//即运行时间除以时间片长度为1,该进程剩下的刚好是一个时间片长度,说明该进程只需在运行一一步就可以运行完毕
                {
                    temp = temp + timecounter;//temp加上最后一个时间片长度就为该进程的结束时间
                    tasks[i].finishtime = temp;
                    tasks[i].runflag = 1;//标记该进程已经执行完毕
                    tasks[i].runtime = copy_task[i].runtime;//为了计算周转时间,运行时间从备份里面还原到最开始的运行时间
                }
                else//仅剩下不足一倍的时间片,则剩余运行时间除以时间片长度<1
                {
                    temp = temp + tasks[i].runtime;//剩余运行时间不够一个时间片长度,则结束时间等于temp加上该进程的运行时间
                    tasks[i].finishtime = temp;
                    tasks[i].runflag = 1;//标记该进程已经运行完毕
                    tasks[i].runtime = copy_task[i].runtime;
                }
            }
        }
    }
    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;
}
 
 
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 zztime = 0, f1, w = 0;
    printf("进程名 到达时间 运行时间 开始时间 结束时间 周转时间\n");
    for (i = 0; i < counter; i++)
    {
        f1 = tasks[i].finishtime - tasks[i].arrivetime;
        zztime += f1;
        printf("%s\t%5.3f\t%5.3f\t%5.3f\t %5.3f\t%5.3f\n", tasks[i].name, tasks[i].arrivetime, tasks[i].runtime, tasks[i].starttime, tasks[i].finishtime, f1);
    }
    printf("平均周转时间=%5.2f\n", zztime / counter);
    return 0;
}
 
 
void main()
{
 
 
    pinput();
    printf("时间片轮转算法。\n\n");
    time();
    poutput();
}
 
 
/*
请输入进程个数:
5
请输入时间片长度:
1
******************************************
请输入进程名称、到达时间、运行时间:(中间用空格隔开)
A 0 4
******************************************
请输入进程名称、到达时间、运行时间:(中间用空格隔开)
B 1 3
******************************************
请输入进程名称、到达时间、运行时间:(中间用空格隔开)
C 2 5
******************************************
请输入进程名称、到达时间、运行时间:(中间用空格隔开)
D 3 2
******************************************
请输入进程名称、到达时间、运行时间:(中间用空格隔开)
E 4 4
时间片轮转算法。
 
进程名 到达时间 运行时间 开始时间 结束时间 周转时间
A       0.000   4.000   0.000    15.000 15.000
B       1.000   3.000   1.000    12.000 11.000
C       2.000   5.000   2.000    18.000 16.000
D       3.000   2.000   3.000    9.000  6.000
E       4.000   4.000   4.000    17.000 13.000
平均周转时间=12.20
*/
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天的大鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值