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;
}

 

转载于:https://www.cnblogs.com/HyattXia/p/10628745.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
处理器系统的进程调度 1.实验目的 加深对进程概念的理解,明确进程和程序的区别; 深入了解系统如何组织进程、创建进程; 进一步认识如何实现处理器调度。 2.实验预备知识 进程的概念; 进程的组织方式; 进程的创建; 进程的调度。 3.实验内容 编写程序完成处理机系统中的进程调度,要求采用时间片轮转调度算法。实验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建原语和进程调度原语;最后编写主函数对所作工作进程测试。 4.提示与讲解 这个实验主要要考虑三个问题:如何组织进程、如何创建进程和如何实现处理器调度。 考虑如何组织进程,首先就要设定进程控制块的内容。进程控制块PCB记录各个进程执行时的情况。不同的操作系统,进程控制块记录的信息内容不一样。操作系统功能越强,软件也越庞大,进程控制块记录的内容也就越多。这里的实验只使用了必不可少的信息。一般操作系统中,无论进程控制块中信息量多少,信息都可以大致分为以下四类: ① 标识信息 每个进程都要有一个惟一的标识符,用来标识进程的存在和区别于其他进程。这个标识符是必不可少的,可以用符号或编号实现,它必须是操作系统分配的。在后面给出的参考程序中,采用编号方式,也就是为每个进程依次分配一个不相同的正整数。 ② 说明信息 用于记录进程的基本情况,例如进程的状态、等待原因、进程程序存放位置、进程数据存放位置等等。实验中,因为进程没有数据和程序,仅使用进程控制块模拟进程,所以这部分内容仅包括进程状态。 ③ 现场信息 现场信息记录各个寄存器的内容。当进程由于某种原因让出处理器时,需要将现场信息记录在进程控制块中,当进行进程调度时,从选中进程进程控制块中读取现场信息进行现场恢复。现场信息就是处理器的相关寄存器内容,包括通用寄存器、程序计数器和程序状态字寄存器等。在实验中,可选取几个寄存器作为代表。用大写的全局变量AX、BX、CX、DX模拟通用寄存器、大写的全局变量PC模拟程序计数器、大写的全局变量PSW模拟程序状态字寄存器。 ④ 管理信息 管理信息记录进程管理和调度的信息。例如进程优先数、进程队列指针等。实验中,仅包括队列指针。
好的,我会尽力回答你的问题。首先,处理器系统的进程调度通常是指操作系统如何在处理器上分配处理时间给不同的进程,以达到最优的效果。下面是针对你提出的四种调度算法的相关讨论: 1. 时间片轮转调度算法 时间片轮转调度算法是一种简而常见的调度算法。它基于一个简的思想,即每个进程被分配一个时间片,并在时间片用完之后被强制中断,以便给其他进程分配处理时间。被中断的进程将被放置在队列的末尾,并在下一轮中继续执行。这种算法适用于需要快速响应的系统。 2. 优先数调度算法 优先数调度算法是一种基于进程优先级的调度算法。每个进程都有一个优先级,优先级越高的进程将被先调度。在这种算法中,进程的优先级可以由用户指定,也可以由系统自动计算。这种算法适用于需要控制特定进程的执行顺序的系统。 3. 最短进程优先调度算法 最短进程优先调度算法是一种基于进程执行时间的调度算法。在这种算法中,每个进程的执行时间被预先指定,调度器会选择执行时间最短的进程来执行。这种算法适用于需要快速响应和处理大量短时间进程的系统。 4. 最短剩余时间优先调度算法 最短剩余时间优先调度算法是一种基于进程剩余执行时间的调度算法。在这种算法中,调度器会选择剩余执行时间最短的进程来执行。这种算法适用于需要处理长时间进程的系统。 下面是一个简的用C语言实现处理器系统的进程调度的示例程序,其中包括四种调度算法的实现。具体代码如下: ```c #include <stdio.h> // 进程控制块结构体 struct PCB { int pid; // 进程ID int priority; // 进程优先级 int time; // 进程执行时间 int remain_time; // 进程剩余执行时间 }; // 时间片轮转调度算法 void RR(struct PCB pcb[], int n, int q) { int time = 0, cnt = 0, i; while (cnt < n) { for (i = 0; i < n; i++) { if (pcb[i].remain_time > 0) { if (pcb[i].remain_time > q) { time += q; pcb[i].remain_time -= q; } else { time += pcb[i].remain_time; pcb[i].remain_time = 0; printf("Process %d finished at time %d.\n", pcb[i].pid, time); cnt++; } } } } } // 优先数调度算法 void PRI(struct PCB pcb[], int n) { int time = 0, cnt = 0, i, j, min_pri, min_pri_idx; while (cnt < n) { min_pri = 99999; for (i = 0; i < n; i++) { if (pcb[i].remain_time > 0 && pcb[i].priority < min_pri) { min_pri = pcb[i].priority; min_pri_idx = i; } } time += pcb[min_pri_idx].remain_time; pcb[min_pri_idx].remain_time = 0; printf("Process %d finished at time %d.\n", pcb[min_pri_idx].pid, time); cnt++; } } // 最短进程优先调度算法 void SJF(struct PCB pcb[], int n) { int time = 0, cnt = 0, i, j, min_time, min_time_idx; while (cnt < n) { min_time = 99999; for (i = 0; i < n; i++) { if (pcb[i].remain_time > 0 && pcb[i].time < min_time) { min_time = pcb[i].time; min_time_idx = i; } } time += pcb[min_time_idx].time; pcb[min_time_idx].remain_time = 0; printf("Process %d finished at time %d.\n", pcb[min_time_idx].pid, time); cnt++; } } // 最短剩余时间优先调度算法 void SRT(struct PCB pcb[], int n) { int time = 0, cnt = 0, i, j, min_time, min_time_idx; while (cnt < n) { min_time = 99999; for (i = 0; i < n; i++) { if (pcb[i].remain_time > 0 && pcb[i].remain_time < min_time) { min_time = pcb[i].remain_time; min_time_idx = i; } } time += pcb[min_time_idx].remain_time; pcb[min_time_idx].remain_time = 0; printf("Process %d finished at time %d.\n", pcb[min_time_idx].pid, time); cnt++; } } int main() { struct PCB pcb[] = { {1, 2, 10, 10}, {2, 1, 5, 5}, {3, 3, 8, 8}, {4, 4, 3, 3} }; int n = 4, q = 2; printf("RR:\n"); RR(pcb, n, q); printf("PRI:\n"); PRI(pcb, n); printf("SJF:\n"); SJF(pcb, n); printf("SRT:\n"); SRT(pcb, n); return 0; } ``` 这个程序实现了时间片轮转、优先数、最短进程优先和最短剩余时间优先四种调度算法,并对一个包含四个进程进程控制块数组进行了调度。你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值