0


实现时间片轮转算法(模拟)计算机操作系统实验5:进程调度算法模拟-RR

实验内容:
实现时间片轮转算法(模拟),要求如下:
1、用到的数据结构
/* PCB /
struct PCB
{
pid_t pid;//进程 PID
int state; //状态信息,1 表示正在运行,0 表示暂停,-1 表示结束
unsigned long runned_time;//已运行时间
unsigned long need_running_time;//剩余运行时间
};
/
PCB集合 */
struct PCB pcb[TOTAL]; //PCB 集合
2、算法思路
算法实现分主函数(main)和分派函数(Dispatch)。
(1)其中主函数(main)的核心功能为:
实现 6 个子进程的创建和子进程 PCB 的初始化。对子进程 PCB 初始化时,状态设为 0,运
行时间由随机数产生。子进程创建后,就通过信号 SIGSTOP 让它处于暂停状态,当被分派
函数(Dispatch)选中后,才能继续执行,输出子进程 x 正在执行的信息。
同时要在主程序里设置定时器,定时器的时间间隔为时间片长度,时间片到,就调用分派函
数(Dispatch)重新选派程序。
(2)分派函数的核心功能:
将正在执行的子进程暂停,状态变为 0,修改已运行时间和剩余运行时间。
如果该子进程剩余时间小于或等于 0,说明执行完毕,PCB 状态改为-1,结束该子进程。
重新选择下一个子进程,状态变为 1,输出该子进程的已运行时间和剩余运行时间,让该子
进程恢复运行。
当所有子进程都结束后,则父程序结束。

代码如下:

#include<stdio.h>#include<stdlib.h>#include<time.h>#include<sys/time.h>#include<signal.h>#include<unistd.h>//宏定义#defineTOTAL6//子进程总数#defineUNIT_TIME200//时间片长度(单位:毫秒)#defineUNIT_TICKS(UNIT_TIME *1000)//计算时间片的ticks数//进程状态#defineSTATE_RUNNING1#defineSTATE_WAITING0#defineSTATE_FINISHED-1voidDispatch(int signum);/* PCB */structPCB{pid_t pid;//进程PIDint state;//状态信息,1表示正在运行,0表示暂停,-1表示结束unsignedlong runned_time;//已运行时间unsignedlong need_running_time;//剩余运行时间};/* PCB集合 */structPCB pcb[TOTAL];//PCB集合//主函数intmain(int argc,char*argv[]){//定义变量int i, j;//初始化随机数种子srand((unsignedint)time(NULL));//初始化PCB集合for(i =0; i < TOTAL; i++){
                pcb[i].state = STATE_WAITING;
                pcb[i].runned_time =0;
                pcb[i].need_running_time =rand()%1000;//随机产生运行时间}//创建子进程for(i =0; i < TOTAL; i++){if((pcb[i].pid =fork())==0){//子进程执行代码while(1){//处于暂停状态,等待信号kill(getpid(), SIGSTOP);//子进程结束if(pcb[i].need_running_time ==0){exit(0);}//打印子进程信息printf("\n");printf("子进程ID:%d\n", pcb[i].pid);printf("已运行时间:%ld\n", pcb[i].runned_time);printf("剩余运行时间:%ld\n", pcb[i].need_running_time);//模拟运行usleep(UNIT_TICKS);
                            pcb[i].runned_time++;
                            pcb[i].need_running_time--;}}}//设置定时器structitimerval itv;
    itv.it_interval.tv_sec =0;
    itv.it_interval.tv_usec = UNIT_TICKS;
    itv.it_value.tv_sec =0;
    itv.it_value.tv_usec = UNIT_TICKS;setitimer(ITIMER_REAL,&itv,NULL);//捕捉SIGALRM信号signal(SIGALRM, Dispatch);//等待子进程结束for(i =0; i < TOTAL; i++){waitpid(pcb[i].pid,NULL,0);}//程序结束printf("\n程序执行结束!\n");return0;}//分派函数voidDispatch(int signum){//暂停正在执行的进程int i;for(i =0; i < TOTAL; i++){if(pcb[i].state == STATE_RUNNING){kill(pcb[i].pid, SIGSTOP);break;}}//检查所有进程是否结束int finished =1;for(i =0; i < TOTAL; i++){//如果剩余运行时间小于零,则说明该进程结束if(pcb[i].need_running_time <0){
                    pcb[i].state = STATE_FINISHED;}elseif(pcb[i].state != STATE_FINISHED){
                    finished =0;}}//如果所有进程都结束,则停止定时器,结束程序if(finished){structitimerval itv;
            itv.it_interval.tv_sec =0;
            itv.it_interval.tv_usec =0;
            itv.it_value.tv_sec =0;
itv.it_value.tv_usec =0;setitimer(ITIMER_REAL,&itv,NULL);return;}//选择下一个要执行的进程for(i =0; i < TOTAL; i++){//找到第一个状态为0的进程if(pcb[i].state == STATE_WAITING){
                    pcb[i].state = STATE_RUNNING;kill(pcb[i].pid, SIGCONT);break;}}}

上述代码的运行结果如下图:
RR实验结果
可见,子进程id一直为0(这里有问题,请各位读者加以改正,有改正的方法可以在评论区评论一下),并且只会创建6个子进程。
如果还有好的方法我也会再分享出来。

标签: 算法 linux c语言

本文转载自: https://blog.csdn.net/weixin_52357218/article/details/128274162
版权归原作者 Tripoke 所有, 如有侵权,请联系我们删除。

“实现时间片轮转算法(模拟)计算机操作系统实验5:进程调度算法模拟-RR”的评论:

还没有评论