Implementar el algoritmo de rotación de intervalos de tiempo (simulación) experimento 5 del sistema operativo de la computadora: Simulación del algoritmo de programación de procesos-RR

Contenido del experimento:
Realice el algoritmo de rotación de intervalos de tiempo (simulación), los requisitos son los siguientes:
1. La estructura de datos utilizada
/* PCB /
struct PCB
{ pid_t pid;//process PID int state;//información de estado, 1 significa en ejecución , 0 significa pausa, -1 significa fin sin firmar long run_time;//tiempo de ejecución transcurrido sin firmar long need_running_time;//tiempo de ejecución restante }; /





PCB set*/
struct PCB pcb[TOTAL]; //PCB set
2. Idea de algoritmo y implementación del algoritmo
La función principal (main) y la función de despacho (Dispatch).
(1) La función central de la función principal (principal) es:
realizar la creación de 6 subprocesos y la inicialización del subproceso PCB. Al inicializar el PCB del subproceso, el estado se establece en 0 y el
tiempo de ejecución se genera mediante números aleatorios. Después de que se crea el proceso secundario, estará en estado suspendido a través de la señal SIGSTOP, y
puede continuar ejecutándose solo después de ser seleccionado por la función de envío (Dispatch), y generar la información que el proceso secundario x está ejecutando.
Al mismo tiempo, se debe configurar un temporizador en el programa principal. El intervalo del temporizador es la duración del intervalo de tiempo. Cuando finalice el intervalo de tiempo, se llamará a la
función de despacho (Dispatch) para volver a seleccionar el programa. .
(2) La función central de la función de despacho:
Pause el proceso secundario en ejecución, cambie el estado a 0 y modifique el tiempo de ejecución transcurrido y el tiempo de ejecución restante.
Si el tiempo restante del subproceso es menor o igual a 0, significa que la ejecución se completa, el estado de la PCB cambia a -1 y el subproceso finaliza.
Vuelva a seleccionar el siguiente subproceso, el estado se convierte en 1, emita el tiempo de ejecución transcurrido y el tiempo de ejecución restante del subproceso, y deje que el subproceso
reanude su ejecución.
Cuando todos los procesos secundarios finalizan, el programa principal finaliza.

el código se muestra a continuación:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

//宏定义
#define TOTAL 6 //子进程总数
#define UNIT_TIME 200 //时间片长度(单位:毫秒)
#define UNIT_TICKS (UNIT_TIME * 1000) //计算时间片的ticks数

//进程状态
#define STATE_RUNNING 1
#define STATE_WAITING 0
#define STATE_FINISHED -1
void Dispatch(int signum);
/* 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集合

//主函数
int main(int argc, char *argv[])
{
    
    
        //定义变量
        int i, j;

        //初始化随机数种子
        srand((unsigned int)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--;
                    }
            }
    }

    //设置定时器
    struct itimerval 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");
    return 0;
}
//分派函数
void Dispatch(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;
            }
            else if (pcb[i].state != STATE_FINISHED)
            {
    
    
                    finished = 0;
            }
    }

    //如果所有进程都结束,则停止定时器,结束程序
    if (finished)
    {
    
    
            struct itimerval 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;
            }
    }

}

El resultado de ejecución del código anterior es el siguiente:
Resultados del experimento RR
se puede ver que la identificación del proceso secundario siempre es 0 ( aquí hay un problema, por favor, los lectores lo corrijan, si hay un método de corrección, pueden comentar en el área de comentarios ), y solo se crearán 6 procesos secundarios.
Si hay una mejor manera, lo compartiré de nuevo.

Supongo que te gusta

Origin blog.csdn.net/weixin_52357218/article/details/128274162
Recomendado
Clasificación