♻️ 资源

大小: 1.62MB

➡️ 资源下载:https://download.csdn.net/download/s1t16/87454535

操作系统

处理机调度

实验目的

多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机,本实验模拟实现处理机调度,以加深了解处理机调度的工作。

实验内容

选择一个调度算法,实现处理机调度

(1)设计一个按优先权调度算法实现处理机调度的程序

(2)设计以时间片轮转实现处理机调度的程序

实验要求

(1)最好采用图形界面;

(2)可随时增加进程;

(3)规定道数,设置后备队列和挂起状态。若内存中进程少于规定道数,可自动从后备队列调度一作业进入。被挂起进程入挂起队列,设置解挂功能用于将指定挂起进程解挂入就绪队列;

(4)每次调度后,显示各进程状态。

实验主要思想

系统为每个进程分配的时间片为 1s,由用户手动输入进程名、优先级、运行时间等信息,由系统分配进程的 ID 号。开始调度时,选择优先级最高的进程作为当前进程,如果进程在 1s 内完成,则放入完成队列;如果没运行完,则其优先级减一重新放入就绪队列。如果用户想要挂起某个进程,可以双击就绪队列中的某一行,将该进程放进挂起队列;若想解除挂起,可以双击挂起队列中的某一行,将该进程重新放入就绪队列。

流程图设计

实验主要函数详解

进程控制块

Mem.h 包含了进程标识符,进程控制信息,进程调度信息等信息,代码块如下:

struct PCB
{
    PCB(){

    }

    PCB(int pid1,int priority1,int time1,int memoryNeeds1){
        pid=pid1;
        priority=priority1;
        time=time1;
        memoryNeeds=memoryNeeds1;
    }

    int pid;
    int state;
    int priority;
    int time;    //要求运行时间
    int memoryNeeds;//the needs memory
    int memoryStart;//the memory start place
    operator <(PCB& a){
        return priority<a.priority;
    }
};

进程调度

/* CPU 调度 */
void MainWindow::pcbsche()
{
	if ( reserve.size() == 0 && ready.size() == 0 )
	{
		t1->stop();
		t2->stop();
		ui->progressBar->setValue( 0 ); ui->tableWidgetRun->clear();
		QMessageBox::about( NULL, "About", "Please add a PCB" );
	}else  {
		for ( vector<PCB>::iterator it = reserve.begin(); it != reserve.end(); )
		{
/* 当道数小于 6 时,从后备队列取出 PCB 添加到就绪队列,直到道数为 6 或者 后备队列为空 */
			if ( ready.size() + hang.size() >= 6 )
				break;


			队 列 !");

if(memo.add(*it)){//if add sucessfully 可以容纳
ui->textBrowserResult->append(QString::number((*it).pid)+" 已进入就绪

			ready.insert( ready.begin(), *it ); it = reserve.erase( it );
			ui->progressBarMemory->setValue( memo.sum );
		}else  {
			ui->textBrowserResult->append( QString::number( (*it).pid ) + "	所需内存过 大,进入就绪队列失败!" );
			it++;
		}
	}
	if ( ready.size() == 0 )
	{
		t1->stop();
		t2->stop();
		ui->progressBar->setValue( 0 ); ui->tableWidgetRun->clear();
		QMessageBox::about( NULL, "About", "就绪队列无进程!" );
		return;
	}
	updateReserve(); if ( scheWay == 0 )
	{
		sort( ready.begin(), ready.end() );
	}
	run = ready.back(); ready.pop_back();
	ui->textBrowserResult->append( QString::number( run.pid ) + " 正在运行" );
	ui->tableWidgetRun->clear();
	ui->tableWidgetRun->setItem( 0, 0, new QTableWidgetItem( QString::number( run.pid ) ) );
	ui->tableWidgetRun->setItem( 0, 1, new QTableWidgetItem( QString::number( run.priority ) ) );
	ui->tableWidgetRun->setItem( 0, 2, new QTableWidgetItem( QString::number( run.time ) ) ); ui->tableWidgetRun->setItem( 0, 3, new
															       QTableWidgetItem( QString::number( run.memoryNeeds ) ) );

	updateReady(); run.time--; if ( scheWay == 0 )
		run.priority--;
	if ( run.time == 0 )
	{
/* 进程已经完成 */
		int memoryStart = run.memoryStart; memo.remove( memoryStart );
		ui->progressBarMemory->setValue( memo.sum );
		ui->textBrowserResult->append( QString::number( run.pid ) + " 运行完成" );
	}else{  /* 如果进程尚未完成,重新添加到就绪队列 ready.insert(ready.begin(),run); */
	}
}
}
/* 响应开始按钮 */
void MainWindow::on_pushButtonSche_clicked()
{
	t1 = new QTimer; connect( t1, SIGNAL( timeout() ), this, SLOT( pcbsche() ) ); QString time = ui->lineEditShiJianPian->text();
	t1->start( time.toInt() * 1000 ); /* 时间片为 1s */
	t2 = new QTimer; connect( t2, SIGNAL( timeout() ), this, SLOT( UpdateProcessBar() ) ); t2->start( time.toInt() * 100 );
	pcbsche();
}


/* 单击获取选中的 pid */
int MainWindow::getPid( const QModelIndex &index )
{
	int row = index.row();
	int pid = index.sibling( row, 0 ).data().toString().toInt(); selectPid = pid;
	return(pid);
}


/* 单击就绪控件 */
void MainWindow::on_tableWidget_Ready_clicked( const QModelIndex &index )
{
}


/* 单击挂起控件 */
void MainWindow::on_tableWidget_Hang_clicked( const QModelIndex &index )

{
}


/* 响应挂起操作 */
void MainWindow::on_pushButtonHang_clicked()
{
	for ( vector<PCB>::iterator it = ready.begin(); it != ready.end(); it++ )
	{
		if ( (*it).pid == selectPid )
		{
			hang.push_back( *it ); memo.remove( (*it).memoryStart ); ready.erase( it );
			ui->progressBarMemory->setValue( memo.sum );
			ui->textBrowserResult->append( QString::number( selectPid ) + "	已挂起" ); updateReady();
			updateHang(); break;
		}
	}
}


/* 响应解挂操作 */
void MainWindow::on_pushButtonWakeUp_clicked()
{
	for ( vector<PCB>::iterator it = hang.begin(); it != hang.end(); it++ )
	{
		if ( (*it).pid == selectPid )
		{
			if ( memo.add( *it ) )
			{
				ready.insert( ready.begin(), *it ); hang.erase( it );
				ui->textBrowserResult->append( QString::number( selectPid ) + "	已解挂" );
				ui->progressBarMemory->setValue( memo.sum ); updateReady();
				updateHang();


				解 挂 ");

}
else



ui->textBrowserResult->append(QString::number(selectPid)+" 内存 足以

				break;
			}
		}
	}
/* 响应暂停按钮,停止时钟 */
	void MainWindow::on_pushButtonSchePause_clicked() /* 暂停 */
	{
		if ( t1->isActive() || t2->isActive() )
		{
			t1->stop();
			t2->stop();
			ui->tableWidgetRun->clear(); updateReady();
		}
	}


/* 生成随机进程 */
	void MainWindow::on_pushButtonSrand_clicked()
	{
		srand( (unsigned) time( NULL ) ); for ( int i = 0; i < 20; i++ )
		{
			PCB a( i, random( 1, 40 ), random( 1, 30 ), random( 1, 30 ) );


			ui->textBrowserResult->append( QString::number( i ) + "	已进入就绪队列!" ); reserve.push_back( a );
		}
		updateReserve();
	}


/* 建立 PCB */
	void MainWindow::on_pushButtonNewPcb_clicked()
	{
		QString name = ui->lineEditName->text(); QString priority = ui->lineEditPriority->text(); QString time = ui->lineEditTime->text(); QString mem = ui->lineEditMem->text();
		ui->lineEditName->clear(); ui->lineEditPriority->clear(); ui->lineEditTime->clear(); ui->lineEditMem->clear();
		if ( ui->comboBox->isEnabled() )
		{
			scheWay = ui->comboBox->currentIndex(); ui->comboBox->hide();
		}
		reserve.push_back( PCB( name.toInt(), priority.toInt(), time.toInt(), mem.toInt() ) ); updateReserve();
	}

实验感想

通过这次实验,我了解了各种处理机调度策略,尤其是时间片轮转法和动态优先级法。也感谢老师的严格要求,让我有机会去了解 Qt 中信号与槽的机制。从中学到了很多 C++ 图形界面开发的知识。

主存空间的分配和回收

实验目的

帮助了解在不同的存储管理方式下,应怎样实现主存空间的分配和回收

实验内容

主存储器空间的分配和回收

实验要求

(1)自行假设主存空间大小,预设操作系统所占大小并构造未分分区表;

(2)结合实验一,PCB 增加为:{PID,要求运行时间,优先权,状态,所需内存大小,主存起始位置,PCB 指针};

(3)采用最先适应算法分配主存空间;

(4)进程完成后,回收内存,并与相邻空闲分区合并。

实验主要思想

用链表管理内存,分配内存时,采用最先适应算法分配空间;回收内存时,需与相邻空闲分区合并。

流程图设计

实验主要函数详解

/* 内存结构体 struct mymemory{ */
mymemory(); mymemory( int f, int l, int s )
{
	front = f; length = l; state = s;
}
bool operator < (const mymemory b) { return(front < b.front); }

int	front; int length;
int	state;                  /* 0 表示 free,1 表示使用 */
};
/* 内存管理函数 class mem */
{
public:
	vector<mymemory>mymem;
	bool add( PCB & a );    /* 返回结果表示是否添加成功 void remove(int memoryStart);//删除元素 a 的空间 mem(); */


	int sum; void tight();
};
/*删除内存块 */
void mem::remove( int memoryStart )
{
	for ( vector<mymemory>::iterator it = mymem.begin(); it != mymem.end(); it++ )
	{
		if ( (*it).front == memoryStart && (*it).state == 1 )
		{
			(*it).state	= 0;
			sum		-= (*it).length; break;
		}
	}

	tight();
}


/* 内存添加 PCB */
bool mem::add( PCB &a )
{
	if ( a.memoryNeeds > 100 )
		return(false);
	for ( vector<mymemory>::iterator it = mymem.begin(); it != mymem.end(); it++ )
	{
		if ( (*it).state == 0 && (*it).length >= a.memoryNeeds )
		{
			sum += a.memoryNeeds;
			mymemory an( (*it).front + a.memoryNeeds, (*it).length - a.memoryNeeds, 0 ); /* 生成 */


			空内存 分 区


			(*it).length = a.memoryNeeds; (*it).state = 1; a.memoryStart = (*it).front; mymem.push_back( an );

			tight();
 v                      return(true);
		}
	}
	cout << "false" << endl; 
        return(false);
}


/* 紧凑 */
void mem::tight()
{
	sort( mymem.begin(), mymem.end() );
	vector<mymemory>::iterator it = mymem.begin() + 1; while ( it != mymem.end() )
	{
		if ( (*it).state == 0 && (*(it - 1) ).state == 0 )
		{
			(*(it - 1) ).length += (*it).length; it = mymem.erase( it );
		}else{
			it++;
		}
	}
}

实验结果

运行前:

开始调度:

添加进程:

挂起:

解挂:

实验感想

通过这次实验,将书上的理论知识和实际代码结合起来,我对分区分配算法有了新的认识。在实验一的基础上添加了内存管理机制。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐