一、要求
- 设计调试运行“时间片轮转”调度算法,给出运行结果。
- 采用“时间片轮转”调度算法对5个进程进行调度,每个进程有一个进程控制块PCB,进程控制块可包含以下信息:进程名、到达时间、需要运行的时间(以时间片为单位)、已用cpu时间(以时间片为单位)、进程状态等等。
- 每个进程的状态可以是就绪W、运行R、或阻塞B三种状态之一。每进行一次调度就打印一次运行进程、就绪队列、以及各进程PCB。重复以上过程,直到所有进程都完成。
实现思路:
例如:设计程序模拟进程的时间片轮转法调度过程。假设初始状态为:有ready个进程处于就绪状态,有blocked个进程处于阻塞状态。采用轮转法进程调度算法进行调度(调度过程中,假设处于执行状态的进程不会阻塞),且每过counter个时间片,唤醒处于阻塞队列队首的进程。
初始队列:
ready=2
blocked=3
counter=5
二、实现
#include <stdio.h>
#include <malloc.h>
// RR(1)
typedef struct PCB_type
{
char name[20]; // 进程名
char state; // 进程状态 R——表示“执行”状态 W——表示“就绪”状态 B——表示“阻塞”状态
int Used_Time; // 已用CPU时间(需运行的时间片个数)
int Arrive_Time; // 到达时间
int Cpu_Time; // 所需CPU总时间
} PCB_type;
typedef struct QueueNode
{
struct PCB_type PCB;
struct QueueNode *next;
} QueueNode;
typedef struct Queue
{
struct QueueNode *head, *tail;
} Queue;
Queue *rq, *bq, *runq;
int count = 0;
// 创建队列
void createq(struct Queue **queue)
{
*queue = (Queue *)(malloc(sizeof(Queue)));
(*queue)->head = (*queue)->tail = NULL;
}
// 入队
void enterq(Queue *q, QueueNode *x)
{
if (q->head == NULL) // 队列为空
{
q->head = q->tail = x;
x->next = NULL;
}
else
{
q->tail->next = x;
q->tail = x;
x->next = NULL;
}
}
// 出队
struct QueueNode *deleteq(Queue *q)
{
QueueNode *p;
if (q->head == NULL)
{
printf("%pQueue is NULL", q);
exit(0);
}
else if (q->head == q->tail)
{
p = q->head;
q->head = q->head->next;
q->tail = q->head;
return p;
}
else
{
p = q->head;
q->head = q->head->next;
return p;
}
}
//模拟调度函数
void dispatch()
{
QueueNode *p;
if (rq->head != NULL || bq->head != NULL)
{
if (rq->head != NULL)
{
p = deleteq(rq); // 出ready队
p->PCB.state = 'R';
p->PCB.Used_Time++;
p->PCB.Cpu_Time--;
printf("The PCB name is %s Used_Time is %d\n", p->PCB.name, p->PCB.Used_Time);
enterq(runq, p); // 入run队
if (p->PCB.Cpu_Time > 0)
{
p->PCB.state = 'W';
deleteq(runq);
enterq(rq, p);
count++;
if (count == 5)
{
if (bq->head != NULL)
{
p = deleteq(bq);
enterq(rq, p);
printf("block中的%s进入ready\n", p->PCB.name);
count = 0;
dispatch();
}
}
else
{
dispatch();
}
}
else
{
deleteq(runq);
free(p);
count++;
if (count == 5)
{
if (bq->head != NULL)
{
p = deleteq(bq);
enterq(rq, p);
printf("block中的%s进入ready\n", p->PCB.name);
count = 0;
dispatch();
}
}
else
{
dispatch();
}
}
}
else
{
count++;
if (count == 5)
{
if (bq->head != NULL)
{
p = deleteq(bq);
enterq(rq, p);
printf("block中的%s进入ready\n", p->PCB.name);
count = 0;
dispatch();
}
else
{
count = 0;
dispatch();
}
}
else
{
dispatch();
}
}
}
else
{
exit(0); // 说明都跑完了,结束
}
}
int main()
{
createq(&rq);
createq(&bq);
createq(&runq);
QueueNode *node[5];
PCB_type pcb[5] = {
{"a", 'N', 0, 1, 3},
{"b", 'N', 0, 2, 3},
{"c", 'N', 0, 3, 3},
{"d", 'N', 0, 4, 4},
{"e", 'N', 0, 5, 2}};
for (int i = 0; i < 5; i++)
{
node[i] = (QueueNode *)malloc(sizeof(QueueNode));
node[i]->next = NULL;
node[i]->PCB = pcb[i];
}
// ready队列3个a、b、c
for (int i = 0; i < 3; i++)
{
enterq(rq, node[i]);
}
// block队列2个d、e
for (int i = 3; i < 5; i++)
{
enterq(bq, node[i]);
}
dispatch();
}