C语言实现单处理器的进程管理

这次实现没有涉及进程的blocked状态!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h> 
#include<stdbool.h>
#include<time.h> 

int identifier_allocate = 0;

// 进程现场信息 
typedef struct Context_Data{
    int PC; // Program Counter
    int IR; // Instruction Register
    int AC; // Accumulator
}CD;

//定义Process Control Block 
typedef struct PCB{
    int identifier; //进程标识符 
    int status; //进程状态,0代表new,1代表ready,2代表running,3代表blocked,4代表exit 
    int runtime; //运行时间 
    int memory_pointer; //内存地址 
    CD context_data; //进程现场信息 
    int priority;  // 权值 
    
}PCB;

//队列节点 
typedef struct QueueNode{
    PCB pcb;
    struct QueueNode *next;
}QueueNode;

//队列 
typedef struct Queue{
    QueueNode *front;
    QueueNode *rear;
}Queue;

//对于权值不同的进程分别设置不同的队列 
Queue Ready_Queue_Priority1, Ready_Queue_Priority2, Ready_Queue_Priority3;

//初始化队列 
int InitQueue(Queue *Q){
    Q->front = (QueueNode *)malloc(sizeof(QueueNode));
    if(Q->front == NULL){
        return 0;
    }
    Q->front->next = NULL;
    Q->rear = Q->front;
    return 1;
}

//进队列 
int EnterQueue(Queue *Q, PCB *x){
    QueueNode *newnode = (QueueNode *)malloc(sizeof(QueueNode));
    if(newnode != NULL){
        newnode->pcb = *x;
        newnode->next = NULL;
        Q->rear->next = newnode;
        Q->rear = newnode;
        return 1;
    }
    return 0;
}

//队头出队列 
int DeleteQueue(Queue *Q, PCB *x){
    if(Q->front == Q->rear){
        return 0;
    }
    QueueNode *p;
    p = Q->front->next;
    Q->front->next = p->next;
    if(Q->rear == p){
        Q->rear = Q->front;
    }
    *x = p->pcb;
    free(p);
    return 1;
}

//判断队列是否为空 
bool isEmpty(Queue *Q){
    if(Q->front == Q->rear){
        return true;
    }
    return false;
}

//创建进程 
void Create(){
    printf("请输入要创建进程的个数:");
    int NumOfProcessToBeCreated = 0;
    scanf("%d", &NumOfProcessToBeCreated);
    
    int i = 0;
    bool failed = false;//用户创建进程时是否出错 
    for(i = 0; i < NumOfProcessToBeCreated; i++){
        printf("请输入该进程运行时间(单位s)和优先级(数字用一个空格隔开;1,2,3优先级递减):\n");
        PCB process;
        scanf("%d %d", &process.runtime, &process.priority);
        
        //除了进程运行时间和权值时输入,其他值全部随机生成 
        if(!failed){
            process.identifier = ++identifier_allocate;
            srand((unsigned)time(NULL));
            process.context_data.AC = rand();
            process.context_data.IR = rand();
            process.context_data.PC = rand();
            process.memory_pointer = rand();
            //设置进程状态new
            process.status = 0;
        }
        
        //对于权值不同的进程分别放入不同的队列中,并且设置进程状态为ready 
        if(process.priority == 1){
            process.status = 1;
            EnterQueue(&Ready_Queue_Priority1, &process);
            failed = false; 
        }
        else if(process.priority == 2){
            process.status = 1;
            EnterQueue(&Ready_Queue_Priority2, &process);
            failed = false; 
        }
        else if(process.priority == 3){
            process.status = 1;
            EnterQueue(&Ready_Queue_Priority3, &process);
            failed = false; 
        }
        //若输入错误,该进程不放入队列,重新输入信息,并且把failed置为true 
        else{
            printf("该进程创建失败!(输入权值错误)。请重新输入!\n");
            NumOfProcessToBeCreated++;
            failed = true; 
        }    
    }
}

//展示ready队列中进程的ID 
void display(){
    int i = 0;
    QueueNode *node;
    node = Ready_Queue_Priority1.front->next;
    printf("\n权值为1的ready队列进程ID:");
    while(node != NULL){
        printf("%d ", node->pcb.identifier);
        node = node->next;
    }
    node = Ready_Queue_Priority2.front->next;
    printf("\n权值为2的ready队列进程ID:");
    while(node != NULL){
        printf("%d ", node->pcb.identifier);
        node = node->next;
    }
    node = Ready_Queue_Priority3.front->next;
    printf("\n权值为3的ready队列进程ID:");
    while(node != NULL){
        printf("%d ", node->pcb.identifier);
        node = node->next;
    }
    printf("\n");
}

//终止函数 
void Terminate(PCB *process){
    //将status置为4,输出相应的信息 
    process->status = 4; 
    printf("\n进程%d执行完毕,退出!\n", process->identifier);
}

//调度策略,对于CPU来说采用时间片轮转的策略,对于选择进程HPF策略 
void Schedule(){
    PCB Running_Process;
    //若三个队列有一个不为空进程便要一直进行下去 
    while(!(isEmpty(&Ready_Queue_Priority1) && isEmpty(&Ready_Queue_Priority2) && isEmpty(&Ready_Queue_Priority3))){
        //依据权值按顺序进行检查 
        if(!isEmpty(&Ready_Queue_Priority1)){
            DeleteQueue(&Ready_Queue_Priority1, &Running_Process);
        }
        else if(!isEmpty(&Ready_Queue_Priority2)){
            DeleteQueue(&Ready_Queue_Priority2, &Running_Process);
        }
        else{
            DeleteQueue(&Ready_Queue_Priority3, &Running_Process);
        }
        
        /*将进程状态改为正在运行的的状态 */ 
        Running_Process.status = 2;
        /*输出正在运行进程的状态信息*/ 
        printf("\n进程%d正在运行......\n", Running_Process.identifier);
        printf("ID         状态   运行时间 内存地址       权值     PC        IR        AC\n");
        printf("%-10d %-6d %-7d  %-14d %-8d %-2d    %-2d    %-2d\n", Running_Process.identifier, Running_Process.status, Running_Process.runtime, 
        Running_Process.memory_pointer, Running_Process.priority, Running_Process.context_data.PC, Running_Process.context_data.IR, Running_Process.context_data.AC);
        display();
        
        /* 对于本程序,采用4s为一个时间片
        若一个进程剩余的运行时间不足一个时间片,就执行相应的时间即可;
        就直接执行一个时间片,若剩余运行时间为0,便时改进程退出 */ 
        
        if(Running_Process.runtime < 4 && Running_Process.runtime > 0){
            Sleep(Running_Process.runtime * 1000);
            Running_Process.runtime = 0;
        }
        else{
            Sleep(4000);
            Running_Process.runtime -= 4;    
        }
        
        if(Running_Process.runtime == 0){
            Terminate(&Running_Process);
        }
        
        /* 若进程为运行结束,按照起权值再次放入相应的队列中去并且设置其状态为ready */ 
        if(Running_Process.priority == 1 && Running_Process.status == 2){
            Running_Process.status = 1;
            EnterQueue(&Ready_Queue_Priority1, &Running_Process);
        }
        else if(Running_Process.priority == 2 && Running_Process.status == 2){
            Running_Process.status = 1;
            EnterQueue(&Ready_Queue_Priority2, &Running_Process);
        }
        else if(Running_Process.priority == 3 && Running_Process.status == 2){
            Running_Process.status = 1;
            EnterQueue(&Ready_Queue_Priority3, &Running_Process);
        }
    }
}

int main(){
    InitQueue(&Ready_Queue_Priority1);
    InitQueue(&Ready_Queue_Priority2);
    InitQueue(&Ready_Queue_Priority3);
    while(1){
        Create();
        Schedule();
    }
    return 0;
}

 

posted @ 2019-03-30 20:10  挠到头秃  阅读(978)  评论(0编辑  收藏  举报