直接看代码
----------------------操作系统作业
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;
}
简单的注释,有数据结构基础的,应该都看得懂,如有错误,请留言指出