与操作系统实验(一):进程控制块的作用相比考虑了优先级,创建的越晚优先级越高。
- 源码
- PCB的定义
#ifndef __PCB_H__
#define __PCB_H__
#define BLOCK -1
#define READY 0
#define RUNNING 1
#define TIME_SLICE 3
#define SYNTHESIZE(varType, varName, funName) \
private: \
varType varName; \
\
public: \
void set##funName(varType varName) { this->varName = varName; } \
\
public: \
varType get##funName() const { return varName; }
#define BREAK_IF(condition) \
if (condition) \
break;
class PCB
{
public:
PCB() {}
PCB(unsigned uid, long counter, long needTime, long arrivalTime, unsigned priority)
{
this->uid = uid;
this->counter = counter;
this->needTime = needTime;
this->arrivalTime = arrivalTime;
this->priority = priority;
this->turnaroundTime = 0;
}
private:
SYNTHESIZE(long, state, State); //状态
SYNTHESIZE(long, counter, Counter); //cpu时间片
SYNTHESIZE(long, arrivalTime, ArrivalTime); //进程到达时间
SYNTHESIZE(long, needTime, NeedTime); //进程运行所需时间
SYNTHESIZE(long, turnaroundTime, TurnaroundTime); //进程周转时间
SYNTHESIZE(unsigned, priority, Priority); //优先级
SYNTHESIZE(unsigned, uid, Uid); //用户标识符
};
#endif
- 优先队列的定义
#ifndef __PRIORITY_QUEUE_H__
#define __PRIORITY_QUEUE_H__
#include "PCB.h"
#define INIT_SIZE 4
class PriorityQueue
{
public:
PriorityQueue();
~PriorityQueue();
public:
void push(PCB *pcb);
PCB *pop();
PCB *getPCB(int index);
bool empty();
int size();
private:
void upFilter(int index);
void downFilter(int index);
private:
PCB **ptr;
int length;
int capacity;
};
#endif
- 优先队列的实现
#include "PriorityQueue.h"
#include <stdlib.h>
#include <assert.h>
#include <iostream>
PriorityQueue::PriorityQueue()
{
ptr = (PCB **)malloc(sizeof(PCB *) * INIT_SIZE);
capacity = INIT_SIZE;
length = 0;
}
PriorityQueue::~PriorityQueue()
{
for (int i = 0; i < length; i++)
{
free(ptr[i]);
}
free(ptr);
ptr = nullptr;
capacity = 0;
length = 0;
}
void PriorityQueue::push(PCB *pcb)
{
if (length == capacity)
{
ptr = (PCB **)realloc(ptr, sizeof(PCB *) * capacity * 2);
capacity *= 2;
}
ptr[length] = pcb;
upFilter(length);
length += 1;
}
PCB *PriorityQueue::pop()
{
assert(!empty());
PCB *ret = ptr[0];
ptr[0] = ptr[length - 1];
length -= 1;
downFilter(0);
return ret;
}
PCB *PriorityQueue::getPCB(int index)
{
assert(index < length);
return ptr[index];
}
bool PriorityQueue::empty()
{
return length == 0;
}
int PriorityQueue::size()
{
return length;
}
void PriorityQueue::upFilter(int index)
{
int par = (index - 1) / 2;
PCB *pcb = ptr[index];
while (index > 0 && pcb->getPriority() > ptr[par]->getPriority())
{
ptr[index] = ptr[par];
index = par;
par = (index - 1) / 2;
}
ptr[index] = pcb;
}
void PriorityQueue::downFilter(int index)
{
int child = 2 * index + 1;
PCB *pcb = ptr[index];
while (child <= length - 1)
{
if (child < length - 1 && ptr[child]->getPriority() < ptr[child + 1]->getPriority())
{
child += 1;
}
if (pcb->getPriority() < ptr[child]->getPriority())
{
ptr[index] = ptr[child];
index = child;
child = 2 * child + 1;
}
else
{
break;
}
}
ptr[index] = pcb;
}
- 主函数
#include "PriorityQueue.h"
#include <random>
#include <ctime>
#include "stdio.h"
#include "PCB.h"
using namespace std;
#define MAX_PROCESS_NUM 10 //一共创建多少个进程
PriorityQueue readyQueue; //就绪队列
PriorityQueue blockQueue; //阻塞队列
PCB *runningProcess; //正在执行的进程
int count = 0; //已创建进程计数器
unsigned int uid = 1; //标识符计数器
long times = 0; //计时器
//检查当前进程指针是否为空,并在为空的情况下尝试运行新进程
//当前有进程可以运行返回true,否则返回false
bool checkNullPointer()
{
bool ret = false;
do
{
BREAK_IF(!runningProcess && readyQueue.empty());
if (!runningProcess)
{
runningProcess = readyQueue.pop();
}
runningProcess->setState(RUNNING);
ret = true;
} while (0);
return ret;
}
void processSchedule()
{
runningProcess->setNeedTime(runningProcess->getNeedTime() - 1);
runningProcess->setCounter(runningProcess->getCounter() - 1);
runningProcess->setTurnaroundTime(runningProcess->getTurnaroundTime() + 1);
//当前进程运行完成
if (runningProcess->getNeedTime() == 0)
{
printf("%4u\t", runningProcess->getUid());
printf("%4ld\t", runningProcess->getArrivalTime());
printf("%7ld\n", runningProcess->getTurnaroundTime());
delete runningProcess;
runningProcess = nullptr;
}
//当前进程时间片用完,送到就绪队列
else if (runningProcess->getCounter() == 0)
{
runningProcess->setCounter(TIME_SLICE);
runningProcess->setState(READY);
readyQueue.push(runningProcess);
runningProcess = nullptr;
}
}
//递增队列中进程的周转时间
void timing()
{
PCB *process;
for (int i = 0; i < readyQueue.size(); i++)
{
process = readyQueue.getPCB(i);
process->setTurnaroundTime(process->getTurnaroundTime() + 1);
}
for (int i = 0; i < blockQueue.size(); i++)
{
process = blockQueue.getPCB(i);
process->setTurnaroundTime(process->getTurnaroundTime() + 1);
}
}
int main(void)
{
default_random_engine e(time(0));
bernoulli_distribution u1(.60); //bool类型随机数,为true就创建一个新进程
uniform_int_distribution<unsigned> u2(2, 9); //随机生成进程的执行所需时间
bernoulli_distribution u3(.20); //bool类型随机数,为true就阻塞当前进程
bernoulli_distribution u4(.40); //bool类型随机数,为true就激活一个被阻塞进程
for (int i = 0; i < 3; i++) //初始化3个进程
{
PCB *process = new PCB(uid++, TIME_SLICE, u2(e), times, count);
process->setState(READY);
readyQueue.push(process);
count++;
}
runningProcess = readyQueue.pop();
runningProcess->setState(RUNNING);
printf("标识符 到达时间 周转时间\n");
while (true)
{
times++;
BREAK_IF(count >= MAX_PROCESS_NUM && !runningProcess && readyQueue.empty() && blockQueue.empty());
if (count < MAX_PROCESS_NUM)
{
bool haveNewProcess = u1(e);
if (haveNewProcess)
{
PCB *newProcess = new PCB(uid++, TIME_SLICE, u2(e), times, count);
newProcess->setState(READY);
readyQueue.push(newProcess);
count++;
}
}
if (!blockQueue.empty())
{
bool active = u4(e);
if (active)
{
PCB *activedProcess = blockQueue.pop();
activedProcess->setState(READY);
readyQueue.push(activedProcess);
}
}
if (!checkNullPointer())
{
continue;
}
processSchedule();
timing();
if (runningProcess)
{
bool blocked = u3(e);
if (blocked)
{
runningProcess->setState(BLOCK);
blockQueue.push(runningProcess);
runningProcess = nullptr;
}
}
}
return 0;
}