FCFS、RR、SPF、PSA、DPSA算法代码---C语言

直接看代码

----------------------操作系统作业
1.FCFS先入先出
2.RR时间片轮转
3.SPF短进程优先即最短处理机运行期优先
4.PSA优先级调度算法
5.DPSA动态优先级调度算法

#pragma once//常用的C/C++预处理指令,只要在头文件的最开始加入这条预处理指令,就能够保证头文件只被编译一次。
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>//size_t(库变量) NULL(宏) 
#include <stdlib.h>//size_t free 
#include <stdbool.h>//定义了 bool 代表 _Bool,true 代表 1,false 代表 0
typedef struct PCB {
	char name;                 //进程名
	int ArrivalTime;           //到达时间
	int ServiceTime;           //服务时间
	int StartTime;             //开始时间
	int FinishTime;            //完成时间
    int ResidualTime;          //剩余服务时间
	double WholeTime;          //周转时间
	double weightWholeTime;    //带权周转时间
    int Priority;              //优先级
}PCB;
typedef PCB DataType;
typedef struct Node {
	DataType data;
	struct Node *next;//队列的存储结构 --共用 
}Node;
typedef struct Queue {//链队列1 的存储结构 
	Node *front;
	Node *rear;
	size_t size;			//队列中有几个元素
}Queue;


typedef struct linkList {//队列2的存储结构 
    Node *head;
    Node *tail;
    size_t size;
}linkList;

void QueueInit(Queue *pqueue) {	//	队列1  队列初始化
	assert(pqueue != NULL);
	pqueue->front = NULL;
	pqueue->rear = NULL;
	pqueue->size = 0;
}

void QueueDestroy(Queue *pqueue)//队列1 把队列删除 
{
	Node *cur = NULL;
	Node *del = NULL;
	assert(pqueue != NULL);
	if (pqueue->front == NULL) {
		return;
	}
	cur = pqueue->front;
	while (cur != NULL) {
		del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
}

Node *CreatNode(DataType data)//创造一个新节点 --共用 
{
	Node *ret = (Node *)malloc(sizeof(Node));
	if (ret == NULL) {
		exit(0);
	}
	ret->data = data;
	ret->next = NULL;
	return ret;
}

void QueuePush(Queue *pqueue, DataType data)//队列1 增加队列 
{
	assert(pqueue != NULL);
	Node *temp = CreatNode(data);//一个新的结点 
	if (pqueue->front == NULL) {
		pqueue->front = temp;
		pqueue->rear = temp;
		//pqueue->rear = pqueue->front = temp;
		++pqueue->size;//大小加一 
	}
	else {
		pqueue->rear->next = temp;
		pqueue->rear = pqueue->rear->next;
		//pqueue->rear = temp;
		++pqueue->size;
	}
}

void QueuePop(Queue *pqueue)//队列1 删除队列头指针指向的队列元素 
{
	assert(pqueue != NULL);
	Node *del = NULL;
	assert(pqueue != NULL);
	if (pqueue->front == NULL) {
		return;
	}
	del = pqueue->front;
	pqueue->front = pqueue->front->next;
	free(del);
	del = NULL;
	++pqueue->size;
    
}

Node *QueueTop(Queue *pqueue)//队列1队头指针 
{
	return pqueue->front;
}


bool QueueEmpty(const Queue *pqueue)//队列1判空 
{
	return pqueue->front == NULL;
}

size_t QueueSize(const Queue *pqueue)//队列1的长度 
{
    return pqueue->size;
}




void linkListInitialize(linkList *plinklist)//队列2的初始化 
{
    assert(plinklist != NULL);
    plinklist->head = NULL;
    plinklist->tail = NULL;
    plinklist->size = 0;    

}

void linkListDestroy(linkList *plinklist)//队列2的删除 
{
	Node *cur = NULL;
	Node *del = NULL;
	assert(plinklist != NULL);
	if (plinklist->head == NULL) {
		return;
	}
	cur = plinklist->head;
	while (cur != NULL) {
		del = cur;
		cur = cur->next;
		free(del);
		del = NULL;
	}
}

void linkListPushBack(linkList *plinklist, DataType data)//与队列2的入队 
{
	assert(plinklist != NULL);
	Node *temp = CreatNode(data);
	if (plinklist->head == NULL) {
		plinklist->head = temp;
		plinklist->tail = temp;
		//pqueue->rear = pqueue->front = temp;
		++plinklist->size;
	}
	else {
		plinklist->tail->next = temp;
		plinklist->tail = plinklist->tail->next;
		//pqueue->rear = temp;
		++plinklist->size;
	}
}

void linkListErase(linkList *plinklist, Node *pnode)//队列2 把结点pnode找到并且删除 (头开始删除) 
{
	Node *cur = NULL;
	assert(plinklist != NULL);
	cur = plinklist->head;
	if ((plinklist->head) == NULL) {
		return;
	}
    if ((plinklist->head) == pnode) {//刚好为队头元素 
        plinklist->head = pnode->next;
        free(pnode);
        pnode = NULL;
        --(plinklist->size);
        return;
    }
    while(cur != NULL) {
        if (cur->next == pnode) {
            cur->next = pnode->next;
            free(pnode);
            pnode = NULL;
            --(plinklist->size);
            break;
        }
        cur = cur->next;
    } 
}

bool linkListEmpty(const linkList *plinkList)//队列2 判空 
{
	return plinkList->head == NULL;
}

size_t linkListSize(const linkList *plinklist)//队列2的长度 
{
    return plinklist->size;
}
Node *Min(linkList *plinklist,int size)//找到满足条件的结点 
{
	Node *p,*q;
	//int flagnum=0;
	int Amin,Smin;
	p=plinklist->head;
	q=plinklist->head;
//	flag=plinklist->head;
	Amin=p->data.ArrivalTime;
	Smin=p->data.ServiceTime;
	while(size>0)
	{
		if(p->data.ArrivalTime<Amin)
		{
			Amin=p->data.ArrivalTime;
		
			q=p;
			
		}
		if(p->data.ArrivalTime==Amin)
		{
				if(p->data.ServiceTime<Smin)
				q=p;
		}
		
		p=p->next;
		size--;
		
	}
	return q;
}
Node *linklistTop(linkList *plinklist)//队列2队头指针 
{
	return plinklist->head;
}

算法部分

void FCFS(Queue *pqueue, PCB pcbs[], int size)
{
    int pcbnumber = size;//
	int time = 0;
	//
	//  |_______|_______|_______|_______|_______|_______|_______|_______|___
	//	0       1       2       3       4       5       6       7       8 

	while (1) {                                                          // e.g.  
		//等待进程
        for (int i = 0; i < size; i++) {
            if (pcbs[i].ArrivalTime == time) {//谁先到达谁就先开始 
                QueuePush(pqueue, pcbs[i]);
			    printf("PCB %c ARRIVAL TIME IS %d\n", pcbs[i].name, time);
                pcbnumber--;
            }
        }
        if (QueueEmpty(pqueue) && pcbnumber == 0) {//已经装满 
			printf("进程执行完毕!\n");
			break;
		}
        //
        //显示时间
//		printf("time is %d \n", time);

		//执行进程
        if (!QueueEmpty(pqueue) && QueueTop(pqueue)->data.ResidualTime == 0) {
            printf("PCB %c FINISH TIME IS %d\n", QueueTop(pqueue)->data.name, time);
            QueuePop(pqueue);//头指针指向的结点删除,指针向上走一个 
        }

        if (!QueueEmpty(pqueue)) {
            QueueTop(pqueue)->data.ResidualTime--;
        }

		time++;
       // sleep(1);
	}
}

void RR(Queue *pqueue, PCB pcbs[], int size)
{ 
	//这里是时间片的大小
	int q = 0;
    printf("please input q:");
    scanf("%d", &q);
	//这个表示本次时间片q剩下多少
	int lessq = 0;
    int pcbnumber = size;
	//表示本进程还需要的服务时间
	int time = 0;
	//
	//  |_______|_______|_______|_______|_______|_______|_______|_______|___
	//	0       1       2       3       4       5       6       7       8 

	while (1) {
		//等待进程
        for (int i = 0; i < size; i++) {
            if (pcbs[i].ArrivalTime == time) {
                QueuePush(pqueue, pcbs[i]);                
                printf("PCB %c ARRIVAL TIME IS %d\n", pcbs[i].name, time);
                pcbnumber--;                
            }
        }
        if (QueueEmpty(pqueue) && pcbnumber == 0) {
			printf("进程执行完毕!\n");
			break;
		}
        //
        //
		//执行进程
        if (lessq == 0){//时间片用完的两种情况 
            if (!QueueEmpty(pqueue) && QueueTop(pqueue)->data.ResidualTime == 0) {//时间片刚好与服务时间相同,使得剩余服务时间为0 
                printf("PCB1 %c FINISH TIME IS %d\n", QueueTop(pqueue)->data.name, time);
                QueuePop(pqueue);
            }
            else {
                if (!QueueEmpty(pqueue) && 
                    QueueTop(pqueue)->data.ServiceTime != //需要的时间比时间片多 ,还需要时间片 
                    QueueTop(pqueue)->data.ResidualTime){
                    pqueue->rear->next = pqueue->front;
                    pqueue->rear = pqueue->rear->next;
                    pqueue->front = pqueue->front->next;
                    pqueue->rear->next = NULL;//把为指针指向时间片刚用完的结点,头指针指向下一个结点  NULL:说明尾指针指向为空,不是循环队列 
                }
            }
            lessq = q;//为新一轮赋予时间片 
		}
		else {
            if (!QueueEmpty(pqueue) && QueueTop(pqueue)->data.ResidualTime == 0) {//需要的时间比时间片少,时间片没用完就完成了 
                printf("PCB %c FINISH TIME IS %d\n", QueueTop(pqueue)->data.name, time);
                QueuePop(pqueue);
                lessq = q;//新的一轮 
            }
        }
        if (!QueueEmpty(pqueue)) {
            QueueTop(pqueue)->data.ResidualTime--;//a4 3/a2 1/b2 1/a0/b0
        }
        lessq--;//1 0/1 0/1 0/1/1
		time++;//1 2 3 4 5 6 7 8
        //sleep(1);
	}
}

//请补充这里的程序 SPF:短进程优先 ,短:进程的运行时间 
//算法思路:先到达的进程先执行,要是同时到达,选择服务时间比较少的一方,实现短作业优先 
void SPF(linkList *plinklist, PCB pcbs[], int size)
{
	int time=0;
	Node *p; 
	int pcbnumber= size;
	for (int i = 0; i < pcbnumber; i++) {//把所有的值都入队列 
            linkListPushBack(plinklist, pcbs[i]);
			printf("PCB %c ARRIVAL TIME IS %d\n", pcbs[i].name, pcbs[i].ArrivalTime);
    }
    pcbnumber=0;//已经装满 
	while (1) 
	 {  //运行过程                                                	
			p=Min(plinklist,linkListSize(plinklist));
		while(1)
		{
			if (!linkListEmpty(plinklist) && p->data.ResidualTime == 0) 
			{ 
                printf("PCB %c FINISH TIME IS %d\n", p->data.name, time);
                linkListErase(plinklist,p);//删除p指定的结点 
                break;
            }
		p->data.ResidualTime--;
		time++;	
		}	
		
	}
	/*if(linkListSize(plinklist)==1)
			{
				time+=linklistTop(plinklist)->data.ServiceTime;
				printf("PCB %c FINISH TIME IS %d\n",linklistTop(plinklist)->data.name, time);
				linkListDestroy(plinklist);
			}*/
 if (linkListEmpty(plinklist) && pcbnumber == 0) {
			printf("进程执行完毕!\n");
		
}
}


void PSA(linkList *plinklist, PCB pcbs[], int size)
{

	int pcbid = 0;
    int pcbnumber = size;
	int time = 0;
    Node *curnode = NULL;
    Node *minnode = NULL;
    //
	//  |_______|_______|_______|_______|_______|_______|_______|_______|___
    //	0       1       2       3       4       5       6       7       8 
    while (1) {
        //等待进程
        for (int i = 0; i < size; i++) {
            if (pcbs[i].ArrivalTime == time) {
                linkListPushBack(plinklist, pcbs[i]);
                //       printf("QueueTop(pqueue)->next == %p\n", QueueTop(pqueue)->next);
                printf("PCB %c ARRIVAL TIME IS %d\n", pcbs[i].name, time);
                pcbnumber--;
                //	    printf("pcbnumber == %d\n", pcbnumber);
            }
        }

        if (linkListEmpty(plinklist) && pcbnumber == 0) {
			printf("进程执行完毕!\n");
			break;
		}
//		printf("time is %d \n", time);
        //
		//执行进程
        //
        if (minnode != NULL && (minnode->data).ResidualTime == 0) {
            printf("PCB %c FINISH TIME IS %d\n", (minnode->data).name, time);
            linkListErase(plinklist, minnode);
            minnode = NULL;
        }
        
        if (!linkListEmpty(plinklist) && minnode == NULL) {
            minnode = NULL;
            curnode = plinklist->head;
            while(curnode != NULL) {
                if (minnode == NULL || curnode->data.Priority < minnode->data.Priority) {
                    minnode = curnode;
                }
                curnode = curnode->next;
            }
        }        


        if (minnode != NULL) {
            --(minnode->data).ResidualTime;
        }
        
		time++;
       // sleep(1);
    }
}


void DPSA(linkList *plinklist, PCB pcbs[], int size)
{

	int pcbid = 0;
    int pcbnumber = size;
	int time = 0;
    Node *curnode = NULL;
    Node *minnode = NULL;
    //
	//  |_______|_______|_______|_______|_______|_______|_______|_______|___
    //	0       1       2       3       4       5       6       7       8 
    while (1) {
        //等待进程
        for (int i = 0; i < size; i++) {
            if (pcbs[i].ArrivalTime == time) {
                linkListPushBack(plinklist, pcbs[i]);                
                printf("PCB %c ARRIVAL TIME IS %d\n", pcbs[i].name, time);
                pcbnumber--;                
            }
        }
		//执行进程
        if (linkListEmpty(plinklist) && pcbnumber == 0) {
			printf("进程执行完毕!\n");
			break;
		}
        if (minnode != NULL && (minnode->data).ResidualTime == 0) {
            printf("PCB %c FINISH TIME IS %d\n", (minnode->data).name, time);
            linkListErase(plinklist, minnode);
            minnode = NULL;
        }
        
        if (!linkListEmpty(plinklist)) {
            minnode = NULL;
            curnode = plinklist->head;
            while(curnode != NULL) {
                if (minnode == NULL || curnode->data.Priority < minnode->data.Priority) {
                    minnode = curnode;
                }
                curnode = curnode->next;
            }
        }        


        if (minnode != NULL) {
            --(minnode->data).ResidualTime;
            ++(minnode->data.Priority);
            printf("PCB %c IS DO\n", (minnode->data).name);
        }
        curnode = plinklist->head;
        while(curnode != NULL) {
            if (curnode == minnode) {
                printf("%c priority ==  %d   ", curnode->data.name , curnode->data.Priority);
                curnode = curnode->next;
                continue;
            }
            (curnode->data.Priority) = (curnode->data.Priority - 1) > 0 ? (curnode->data.Priority) - 1 : 0;
            printf("%c priority ==  %d   ", curnode->data.name , curnode->data.Priority);
            curnode = curnode->next;
        }
        printf("\n");
		time++;       
    }
}


int main()
{
    int processnumber = 0;
	Queue queue;
    linkList linklist;
 // char name;
 // int ArrivalTime;        //到达时间
 // int ServiceTime;        //服务时间
 // int StartTime;          //开始时间
 // int FinishTime;         //完成时间
 // int ResidualTime;       //剩余服务时间
 // double WholeTime;          //周转时间
 // double weightWholeTime;    //带权周转时间
 // int Priority;           //优先级
   // PCB pcbs[] = {p1};
    printf("please input process number: ");
    scanf("%d", &processnumber);//pcb的内存和processnumber相同 
    PCB *pcbs = (PCB *) malloc (sizeof(PCB) * processnumber);
    memset(pcbs, 0, sizeof(PCB) * processnumber);// C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
    for (int i = 0; i < processnumber; i++) {
        printf("process->name: ");
        //这里有坑 :
        //  可以用 scanf(" %c")    //   %c 前面加一个空格
        //  或者在上一行加一个getchar()
        //  getchar();
        scanf(" %c",&(pcbs[i].name));
        printf("process->ArricalTime: ");//pcb[[name,arrivaltime,servicetime,priority],[],[]......[]] processnumber个 
        scanf("%d",&(pcbs[i].ArrivalTime));
        printf("process->ServiceTime: ");
        scanf("%d",&(pcbs[i].ServiceTime));
        pcbs[i].ResidualTime = pcbs[i].ServiceTime;//!!!!! 
        printf("process->Priority: ");
        scanf("%d",&(pcbs[i].Priority));
    }
	int input = 0;
	QueueInit(&queue); 
    linkListInitialize(&linklist);//初始化空的链队列
	printf("1. FCFS   2.RR   3.SPF   4.PSA   5.DPSA\n");
	printf("Please input number: ");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		FCFS(&queue, pcbs, processnumber); //先入先出 
		break;
	case 2:
		RR(&queue, pcbs, processnumber);  //时间片轮转 
		break;
	case 3:
       SPF(&linklist, pcbs, processnumber); //短进程优先即最短处理机运行期优先 
		break;
	case 4:
        PSA(&linklist, pcbs, processnumber); //优先级调度算法 
		break;
	case 5:
        DPSA(&linklist, pcbs, processnumber); //动态优先级调度算法 
		break;
	default:
		break;
	}
    linkListDestroy(&linklist);
	QueueDestroy(&queue);
	return 0;
}

简单的注释,有数据结构基础的,应该都看得懂,如有错误,请留言指出

  • 11
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值