实验涉及仪器设备和材料清单(或软件)
计算机:某 PC
操作系统:Ubuntu 18.04
IDE: Qt 12.2 , gcc 64 位编译器, qt creator
代码分析
1. 原型设计
根据实验要求,设计出大致的 UI 界面来模拟进程的调度
界面大概由三部分组成.
第一部分:队列和调度算法选择
能够模拟控制操作系统从进程就绪队列中通过不同算法选择进程来执行
对于阻塞队列,配置交互按钮使其能够根据调度算法唤醒其中的被阻塞进程到就绪队列
继续运行
第二部分:cpu 中进程运行状态以及阻塞当前进程
展示 cpu 当前运行的状态,当前所运行的进程的情况,时间片使用情况.
由于时间原因,未能实现时间片算法调度.
第三部分:创建进程
根据指定的优先级,运行时间,id 号来创建一个进程且加入到就绪队列中.
原型设计图:
2. 软件逻辑架构设计
使用面向对象的方法,每个对象承担自己的功能.
Process 类:
进程的抽象.继承于 Qt c++类库提供的 QGraphicItem 与 QPropertyAnimation 两个类,
使其具有绘制图形与产生动画的能力.其属性如下图:
表征进程状态的是一个枚举变量,定义如下:
BaseQueue 类:
队 列 的 抽 象 . 继 承 自 QGraphicsItem 类 使 其 具 有 绘 制 图 形 的 能 力 , 继 承 自
priority_queue_t 使其成为优先级队列.
类型 priority_queue_t 定义如下:
不同的调度算法组成一个枚举类,再此定义:
BlockingQueue 与 ReadyQueue:
分别是阻塞队列与就绪队列的抽象.继承自 BaseQueue.二者主要的不同是对进程动画
的控制,还有阻塞队列对进程具有唤醒功能.
CPU 类:
cpu 的抽象,引用两个队列,从而能够从中获取就绪进程或放入阻塞进程.能够运行进
程,消耗其时间片,也能够空运转(stop).cpu 类的对象被单独的置于一个线程中用来处
理进程的调度.私有成员定义如下:
MainWindow 类:
主窗口类.负责整个进程调度模拟的控制.各个组件的创建,绘制,通信.是最核心的
类.MainWindow 运行在主线程.具备能够与运行在子线程的 CPU 对象进行通信.通
过 QT 的信号槽机制能够较为容易的实现多线程间通信.MainWindow 类中定义了大量
的槽函数使其能够接收不同对象传来的控制请求,使得进程调度的模拟能够按预期进
行.
私有成员定义如下:
槽函数定义如下:
3. 代码实现
1) . 整个代码实现的核心是完成进程从就绪队列到 CPU,再到阻塞队列,再到就绪队列
的流转.得益于指针的强大与 QT 信号槽机制的简单易用,这点能够被较为容易的实现
出来.
MainWindow 的构造函数:
1. MainWindow::MainWindow(QWidget *parent) :
2.
3.
4.
5.
6.
7.
8.
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setGeometry(0,0,1920,1080);
this->setWindowTitle("Process Scheduling");
//创建图形绘制面板
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
view = new CustomView(this);
view->setGeometry(0,0,1920,1080);
scene = new CustomeScene(view);
view->setScene(scene);
//创建就绪队列
readyQueue = new ReadyQueue(QColor(Qt::green),QSize(QUEUE_WIDTH,QUEUE_HEIGHT));
readyQueue->setPos(100,300);
connect(static_cast(readyQueue),SIGNAL(drawProcess(Process*)),scene,SLOT(onDra
wProcess(Process*)));
connect(readyQueue,SIGNAL(startAnimation(Process*,QPoint)),this,SLOT(onStartAnimation(Process
*,QPoint)),Qt::QueuedConnection);
connect(readyQueue,SIGNAL(startBlockingAnimation(Process*,QPoint)),this,SLOT(onStartBlockingA
nimation(Process*,QPoint)));
//创建阻塞队列
blockingQueue = new BlockingQueue(QColor(Qt::red),QSize(QUEUE_WIDTH,QUEUE_HEIGHT));
blockingQueue->setPos(100,550);
connect(static_cast(blockingQueue),SIGNAL(drawProcess(Process*)),scene,SLOT(onD
rawProcess(Process*)));
//创建 cpu 对象并将其移入子线程
cpu = new CPU(CPU_RADIUS,blockingQueue,readyQueue,QPoint(1300,200));
cpuThread = new QThread();
cpu->moveToThread(cpuThread);
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
connect(cpu,SIGNAL(removeProcess(Process*)),scene,SLOT(onRemoveProcess(Process*)),Qt::Queu
edConnection);
connect(cpu,SIGNAL(blockAnimation(Process*)),this,SLOT(onBlockAnimation(Process*)),Qt::Queue
dConnection);
connect(cpuThread,SIGNAL(started()),cpu,SLOT(run()));
readyQueue->setCenterPoint(CPU::centerPoint);
blockingQueue->setCenterPoint(CPU::centerPoint);
//将图形对象加入到绘制面板
scene->addItem(cpu);
scene->addItem(blockingQueue);
scene->addItem(readyQueue);
int startLocationX = 600;
pidLabel.setText("pid");
pidLabel.setGeometry(startLocationX+60,800,50,50);
pidEdit.setGeometry(startLocationX+120,800,50,50);
pidEdit.setText("01");
timeLabel.setText("time");
timeLabel.setGeometry(startLocationX+200,800,50,50);