5月6日

进程调度模拟算法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

/*进程控制块数据结构*/
typedef struct node
{
    char name[10];     /*进程名*/
    int prio;          /*进程优先级*/
    int round;         /*循环轮转法进程每次轮转的时间片*/
    int cputime;       /*进程累计消耗的CUP时间*/
    int needtime;      /*进程到完成还需要的CUP时间*/
    int count;         /*循环轮转法一个是时间片内进程运行时间*/
    char state;        /*进程的状态:'R':运行,'W':等待,'F':结束*/
    struct node *next; /*指向下一个进程的链指针*/
} PCB;

PCB *finish, *ready, *tail, *run; /*指向三个队列的队首的指针,
                                    finish为完成队列头指针,
                                    ready为就绪队列头指针,
                                    tail为就绪队列的队尾指针,
                                    run为当前运行进程头指针*/

int N; /*定义进程的数目*/

void firstin(void);              // 调度就绪队列的第一个进程投入运行;
void print1(char a);             // 打印表头行信息
void print2(char chose, PCB *p); // 打印每一行的状态信息
void print(char chose);          // 打印每执行一次算法后所有的进程的状态信息
void insert_prio(PCB *q);        // 在优先数算法中,将尚未完成的PCB按优先数顺序插入到就绪队列中;
void prior_init(char chose);     // 进程优先级法初始化将进程按优先级插入到就绪队列里
void priority(char chose);       // 进程优先级算法总函数
void insert_rr(PCB *q);          // 在轮转法中,将执行了一个时间片单位(为2),但尚未完成的进程的PCB,插到就绪队列的队尾;
void roundrun_init(char chose);  // 循环轮转法初始化将就绪队列保存为FIFO队列
void roundrun(char chose);       // 循环轮转法总算法

void main() // 主函数
{
    char chose = ' ';
    while ((chose != 'q') && (chose != 'Q'))
    {
        fflush(stdin);
        printf("选择进程优先级算法请输入P,选择循环轮转算法请输入R,退出请输入Q\n");
        printf("请输入你的选择:");
        scanf("%c", &chose);
        if ((chose != 'q') && (chose != 'Q'))
        {
            system("cls");
            if ((chose == 'P') || (chose == 'p'))
            {

                prior_init(chose);
                priority(chose);
                system("cls");
            }

            else if ((chose == 'r') || (chose == 'R'))
            {

                roundrun_init(chose);
                roundrun(chose);
                system("cls");
            }
        }
    }
    printf("谢谢使用!\n");
}

void firstin(void) // 调度就绪队列的第一个进程投入运行;
{
    if (ready != NULL)
    {
        run = ready;
        ready = ready->next;
        run->state = 'R';
        run->next = NULL;
    }
    else
    {
        run = NULL;
    }
}

void print1(char a) // 打印表头行信息
{
    if (toupper(a) == 'P')
    {
        printf("name  cputime  needtime priority state \n");
    }
    else
    {
        printf("name  cputime  needtime count round state \n");
    }
}

void print2(char chose, PCB *p) // 打印每一行的状态信息
{
    if (toupper(chose) == 'P')
    {
        printf("%s\t%d\t%d\t%d\t%c\n", p->name, p->cputime, p->needtime, p->prio, p->state);
    }
    else
    {
        printf("%s\t%d\t%d\t%d\t%d\t%c\n", p->name, p->cputime, p->needtime, p->count, p->round, p->state);
    }
}
void print(char chose) // 打印每执行一次算法后所有的进程的状态信息
{
    PCB *p;
    print1(chose);
    if (run != NULL)
    {
        print2(chose, run);
    }

    p = ready;
    while (p != NULL)
    {
        print2(chose, p);
        p = p->next;
    }

    p = finish;
    while (p != NULL)
    {
        print2(chose, p);
        p = p->next;
    }
}
void insert_prio(PCB *q) /*在优先数算法中,将尚未
                         完成的PCB按优先数顺序插入到就绪队列中;*/
{
    PCB *p, *s, *r; /*p,r用来控制就绪队列滚动,S指向插入的队列*/

    s = q;
    p = ready;
    r = p;

    if (s->prio > ready->prio) // 要插入的进程的优先级大于ready的优先级
    {
        s->next = ready;
        ready = s;
    }
    else // 要插入的进程的优先级不大于ready的优先级
    {
        while (p)
        {
            if (p->prio >= s->prio)
            {
                r = p;
                p = p->next;
            }
            else
                break;

        } // 找到要插入的位置
        s->next = p;
        r->next = s;
    }
}

void prior_init(char chose) /*进程优先级法初始化
                         将进程按优先级插入到就绪队列里*/
{
    PCB *p;
    int i, time;
    char na[10];
    ready = NULL;
    finish = NULL;
    run = NULL;
    printf("输入进程 的个数 N:\n");
    scanf("%d", &N);
    for (i = 0; i < N; i++)
    {
        p = (PCB *)malloc(sizeof(PCB));
        printf("输入第%d个进程名\n", i + 1);
        scanf("%s", na);
        printf("完成进程需要的时间片数\n");
        scanf("%d", &time);
        strcpy(p->name, na);
        p->cputime = 0;
        p->needtime = time;
        p->state = 'W';
        p->prio = 50 - time; // 设置进程优先值初值

        if (ready == NULL)
        {
            ready = p;
            ready->next = NULL;
        }
        else
        {
            insert_prio(p);
        }
        printf("当前就绪队列的进程的信息\n");
        print(chose);
    }
    printf("%d个进程已按优先级从高到低进到就绪队列中\n", N);
    printf("按回车键开始模拟优先级算法.....\n");
    fflush(stdin);
    getchar();
    firstin();
}
void priority(char chose) // 进程优先级算法总函数
{
    int i = 1;

    while (run != NULL)
    {
        run->cputime += 1;
        run->needtime -= 1;
        run->prio -= 1;
        if (run->needtime == 0)
        {
            run->next = finish;
            finish = run;
            run->state = 'F';
            run->prio = 0;
            run = NULL;
            firstin();
        }
        else
        {
            if ((ready != NULL) && (run->prio < ready->prio))
            {
                run->state = 'W';
                insert_prio(run);
                run = NULL;
                firstin();
            }
        }

        print(chose);
    }

    getchar();
}
void insert_rr(PCB *q) // 在轮转法中,将执行了一个时间片单位(为2),
                       // 但尚未完成的进程的PCB,插到就绪队列的队尾;
{
    tail->next = q;
    tail = q;
    q->next = NULL;
}
void roundrun_init(char chose) /*循环轮转法初始化
                               将就绪队列保存为FIFO队列*/
{
    PCB *p;
    int i, time;
    char na[10];
    ready = NULL;
    finish = NULL;
    run = NULL;
    printf("\t\t循环轮转算法模拟全过程\n\n");
    printf("输入进程 的个数 N:\n");
    scanf("%d", &N);
    for (i = 0; i < N; i++)
    {
        p = (PCB *)malloc(sizeof(PCB));
        printf("输入第%d个进程名\n", i + 1);
        scanf("%s", na);
        printf("完成进程需要的时间片数\n");
        scanf("%d", &time);
        strcpy(p->name, na);
        p->cputime = 0;
        p->needtime = time;
        p->count = 0;
        p->state = 'W';
        p->round = 2;
        if (ready != NULL)
        {
            insert_rr(p);
        }
        else
        {
            p->next = ready;
            ready = p;
            tail = p;
        }
        printf("当前就绪队列的进程的信息\n");
        print(chose);
    }
    printf("%d个进程已按FIFO进到就绪队列中\n", N);
    printf("按回车键开始模循环轮转算法.....\n");
    fflush(stdin);
    getchar();
    run = ready;
    ready = ready->next;
    run->state = 'R';
}
void roundrun(char chose) // 循环轮转法总算法
{
    int i = 1;
    while (run != NULL)
    {
        run->cputime += 1;
        run->needtime -= 1;
        run->count += 1;
        if (run->needtime == 0)
        {
            run->next = finish;
            finish = run;
            run->state = 'F';
            run->prio = 0;
            run = NULL;
            if (ready != NULL)
            {
                firstin();
            }
        }
        else
        {
            if (run->count == run->round)
            {
                run->count = 0;
                if (ready != NULL)
                {
                    run->state = 'W';
                    insert_rr(run);
                    firstin();
                }
            }
        }

        print(chose);
    }
    getchar();

 

posted @ 2025-05-08 15:44  KuanDong24  阅读(8)  评论(0)    收藏  举报