Operating system programming job 2-process scheduling (C ++ implementation)

topic

Please write a program to simulate the scheduling of several processes. Assume that the state of the process is divided into two types of execution and ready.
Each process can be represented by its PCB, without creating a real process.
The PCB is organized in a linked list and is divided into three queues:
freeQueue: a blank PCB queue
readyQueue: a ready queue
runningQueue: an execution queue

When the program starts to run, the user enters the number of processes n, and the time t0 / t1 /.../ tn each process needs to run.
The program takes the PCB creation process from the blank PCB queue and inserts it into readyQueue.
The process is scheduled in a random manner , that is, a process is randomly selected from the ready queue and put into operation (that is, the state variable in the PCB is assigned to "run"). Correspondingly modify the queue where it is, and the process that was originally in the running state needs to be changed to the "ready" state and inserted into the readyQueue.
Assuming that the time slice is 2, after each time the process is scheduled to run, the time it still needs to run should be reduced by 2 until it reaches 0, which means that the process is completed. Need to recycle PCB to freeQueue .
Every time scheduling occurs, an example of the information that needs to be printed is:

Sched: P0(Running -> Ready), P3(Ready -> Running)
Running: P3
Ready: P1->P2->P0

The above information indicates that P0 is in the running state during scheduling, and P3 is selected to run. The PCB of the P0 process enters the ready queue and is at the end of the queue. The ready queue is to output the process name in the order of the queue nodes.
Example snippet code:
#define free 0
#define ready 1
#define running 2
#define ts 2 / * time slice /
struct PCB {
int pid; /
process ID /
int pstate; /
process state * /
char pname; / image name /
int ptime; /
remaining runtime * /
struct PCB pnext; / next PCB * /
}

Code

//
// Created by Jintao on 2019/12/14.
//


// 题目:
// 请编写一个程序,模拟若干进程调度执行的情况。假设进程的状态分为执行和就绪两种。
// 每个进程以其PCB为代表即可,无需创建真正的进程。以链表的方式组织PCB,分为三个队列:
// freeQueue:一个空白PCB队列
// readyQueue:一个就绪队列
// runningQueue:一个执行队列
//
// 程序开始运行时,用户输入进程数量n,以及每个进程需要运行的时间t0/t1/…/tn。
// 程序从空白PCB队列中取出PCB创建进程,插入readyQueue。
//
// 进程的调度采用随机的方式,即从就绪队列中随机选择一个进程投入运行(就是将该PCB中的状态变量赋值为“运行”)。
// 相应的修改其所在队列,并且原来处于运行态的进程需要转变为“就绪”态,插入readyQueue。
// 假设时间片是2,进程每次调度运行后,其还需运行的时间应该减少2,直至为0,即表示该进程执行完毕。需要回收PCB到freeQueue。
// 每次发生调度的时候,需要打印信息示例:
//
// Sched: P0(Running -> Ready), P3(Ready -> Running)
// Running: P3
// Ready: P1->P2->P0
//
// 上述信息表示调度时P0处于运行态,选择P3运行,P0进程的PCB进入就绪队列,并且在队尾。就绪队列是按照队列节点次序输出进程名称。



#include <cstring>
#include<cstdio>
#include<cstdlib>
#include<ctime>

const int timeSlice = 2; // 时间片
/// 进程状态 枚举
enum struct PState {
    free, ready, running
};


struct PCB {
    int pid;  // 进程id
    PState pstate;  // 进程状态
    char name[20];  // 进程名称 P0, P1, P2...
    int time;  // 剩余运行时间
    PCB *next;  // 下一个PCB

    PCB() : next(nullptr) {}

    PCB(int pid, PState pstate, char *name, int time, PCB *next) :
            pid(pid), pstate(pstate), time(time), next(next) {
        strcpy(this->name, name);
    }

};

/// PCB链表
struct PCBList {
    PCB *head;
    int length;

    PCBList() : length(0) {
        head = new PCB;
    }

    ~PCBList() {
        __freeAllPCB();
        delete head;
    }

    /// 加在链表的首部
    void push(PCB *pPcb) {
        pPcb->next = head->next;
        head->next = pPcb;
        length += 1;
    }

    /// 随机pop一个PCB
    PCB *randPop();

    bool empty() {
        return length == 0;
    }

    void printList();

    /// 释放PCB资源,不包括head
    void __freeAllPCB();
};

/// 记录PCB调用信息
struct PCBSched {
    PCB *pcb;
    PState from;
    PState to;

    /// 获取PCB调用信息
    char *getInfo(char *dest);

    PCBSched() = default;

    PCBSched(PCB *pcb, PState from, PState to) : pcb(pcb), from(from), to(to) {}
} pcbSched[2];

PCBList freeList;
PCBList readyList;
PCBList runningList;


/// 初始化readyList, 理论最大进程数
int initReadyList();

/// 进程调度
void schedule();

/// 打印信息
void printInfo();


int main() {
    srand(time(nullptr));
    initReadyList();
    // A'+B' = (AB)'
    while (!(runningList.empty() && readyList.empty())) {
        schedule();
        printInfo();
    }
}


PCB *PCBList::randPop() {

    int randNum = rand() % length;

    // get *randPCB
    PCB *pPcb = head->next, *pPrev = head;  // pPrev 记录 前一个pPcb的值
    while (randNum--) {
        pPrev = pPcb;
        pPcb = pPcb->next;
    }
    // pop pPcb
    PCB *pOld = pPcb;  // 存储 要pop返回的PCB
    pPrev->next = pPcb->next;
    length -= 1;
    return pOld;
}

void PCBList::printList() {
    if (!length) {
        printf("\n");
        return;
    }
    PCB *pPcb = head->next;
    while (pPcb->next != nullptr) {
        printf("%s(%d)->", pPcb->name, pPcb->time);
        pPcb = pPcb->next;
    }
    printf("%s(%d)\n", pPcb->name, pPcb->time);
}

void PCBList::__freeAllPCB() {
    PCB *pPcb = head->next;
    PCB *pOld;
    while (length--) {
        pOld = pPcb;
        pPcb = pPcb->next;
        delete pOld;
    }
}

char *__pStateToStr(char *dest, PState pState);

char *PCBSched::getInfo(char *dest) {
    char pStateTemp[2][10];
    sprintf(dest, "%s(%s -> %s)", pcb->name, __pStateToStr(pStateTemp[0], from),
            __pStateToStr(pStateTemp[1], to));
    return dest;
}

int initReadyList() {
    int procNum;  // 进程数量

    scanf("%d", &procNum);
    for (int i = 0; i < procNum; i++) {

        char name[20];
        sprintf(name, "P%d", i);
        int pTime;
        scanf("%d", &pTime);

        readyList.push(new PCB(i, PState::ready, \
                name, pTime, nullptr));
    }
    return procNum;
}

void schedule() {
    if (!runningList.empty()) {
        PCB *pcb = runningList.randPop();
        if ((pcb->time -= timeSlice) > 0) {
            pcb->pstate = PState::ready;
            readyList.push(pcb);
            pcbSched[0] = PCBSched(pcb, PState::running, PState::ready);
        } else {
            pcb->time = 0;
            pcb->pstate = PState::free;
            freeList.push(pcb);
            pcbSched[0] = PCBSched(pcb, PState::running, PState::free);
        }
    } else {
        pcbSched[0].pcb = nullptr;
    }

    if (!readyList.empty()) {
        PCB *pcb = readyList.randPop();
        pcb->pstate = PState::running;
        runningList.push(pcb);
        pcbSched[1] = PCBSched(pcb, PState::ready, PState::running);
    } else {
        pcbSched[1].pcb = nullptr;
    }


}

char *__pStateToStr(char *dest, PState pState) {
    switch (pState) {
        case PState::free:
            strcpy(dest, "Free");
            break;
        case PState::ready:
            strcpy(dest, "Ready");
            break;
        case PState::running:
            strcpy(dest, "Running");
            break;
    }
    return dest;
}


void printInfo() {
    char infoTemp[2][40];
    if (pcbSched[1].pcb == nullptr) {
        printf("Sched: %s\n", \
                pcbSched[0].getInfo(infoTemp[0]));
    } else if (pcbSched[0].pcb == nullptr) {
        printf("Sched: %s\n", \
                pcbSched[1].getInfo(infoTemp[0]));
    } else {
        printf("Sched: %s, %s\n", \
                pcbSched[0].getInfo(infoTemp[0]), pcbSched[1].getInfo(infoTemp[1]));
    }

    printf("Running: ");
    runningList.printList();
    printf("Ready: ");
    readyList.printList();
    printf("Free: ");
    freeList.printList();
    printf("\n");
}


operation result

operation result

Same series

2. Operating system programming job 2-process scheduling (implemented by C ++)
https://blog.csdn.net/qq_40939814/article/details/103548436

3. Operating system programming job 3-process synchronization (semaphore mechanism) (C ++ pseudocode implementation)
https://blog.csdn.net/qq_40939814/article/details/103548527

5. Operating system programming operation 5-address conversion of analog paging system (formula method and hard spelling method) (C ++ implementation)
https://blog.csdn.net/qq_40939814/article/details/103548645

Published 9 original articles · Likes2 · Visits 559

Guess you like

Origin blog.csdn.net/qq_40939814/article/details/103548436