弄了三天,有三点感想:
1.原来还是那么菜。稍微复杂一点的程序,类的设计,过程的控制,等等弄的焦头烂额的。不知道哪个年头能达到那些写linux源码,stl源码的人的水平。每天提醒自己一句,“设计模式摆在书桌上已经很久了!”
2.程序还是得天天练啊,数据结构很重要。双连表的建立,结点插入,删除及排序等操作的调试费了我大部分时间。不过数据结构设计好了,其他的代码是水到渠成,写的是酣畅淋漓。每天提醒自己一句,“你会眯着眼睛把各种排序算法写出来吗?”。
3.纸上得来终觉浅,实践才能有提高。这些天,基本上天天不是在看操作系统教材就是看linux内核分析的书,本以为写这样的程序是驾轻就熟的事了,但一入题分析,马上又得翻课本了,好失败。
1、实验题目
1) 设计一个按优先权调度算法实现处理机调度的程序;
2) 设计按时间片轮转算法实现处理机调度的程序。
2、要求
1) 可以随机输入若干进程,并按优先权排序(为了方便演示,排序单独写成一个函数来调用,实际在加入队列时就排序会更好些);
2) 从就绪队列的首选进程开始运行:优先权-1/要求运行时间-1,要求当运行时间=0时,撤销该进程;
3) 重新排序,进行下一轮调度;
4) 采用图形界面实现,可以适当加入动态动画效果;
5) 可以随时增加进程;
6) 规定道数,设置后备队列和挂起状态。若内存中进程少于规定道数,可以自动从后备队列(不在内存中吗?)调度一作业进入。被挂起进程进入挂起队列,设置解挂功能用于将指定挂起进程解挂并加入就绪队列。
7) 每次调度后,显示各进程的状态。
3.程序截图(mfc版)

4.源码
附上纯C++版的源码,后来根据实验要求又改了个mfc版本的,根据需要有些细节有出入。
pcglist.h,为进程链表结构
#ifndef PCBLIST_H
#define PCBLIST_H
#include
<
cstddef
>

#define TASK_RESERVE
0
#define TASK_READY
1
#define TASK_RUNNING
2
#define TASK_WAITE
3
#define TASK_HANG
4
#define TASK_OVER
5
#define MAX_PID
100
#define MAX_PRIO
30
#define DEFAULT_TIME_SLICE
10

typedef struct PCB

...
{
int pid;
int state;
int priority;
int time_slice; //要求运行时间
int time_ran; //已运行时间
struct PCB* prep;
struct PCB* nextp;

PCB():pid(0),state(0),priority(0),time_slice(0),time_ran(0),prep(NULL),nextp(NULL)...{}
bool run()

...{
if( time_ran<time_slice )

...{
if( priority>0 ) --priority;
++time_ran;
state=TASK_RUNNING;
return true;
}
else

...{
state=TASK_OVER;
return false;
}
}
}
Cpcb;

class Cpcblist

...
{
public:
Cpcb* head;
Cpcb* end;
public:
int count;
public:

Cpcblist():count(0)...{end=new Cpcb;head=end;}
void push_back(Cpcb*);
void insert_before(Cpcb* inpcb,Cpcb* nextpcb);
Cpcb* pop(Cpcb*);
Cpcb* pop_front();
void remove(Cpcb*);
//void swap(Cpcb*,Cpcb*);
void sort();
~Cpcblist();
}
;
#endif
#include
"
pcblist.h
"

Cpcblist::
~
Cpcblist()

...
{
Cpcb* tp=head;
Cpcb* p=tp;
while( tp=tp->nextp )

...{
delete p;
p=tp;
}
}

void
Cpcblist::push_back(Cpcb
*
p)

...
{
if( head==end )

...{
head=p;
p->nextp=end;
end->prep=p;
}
else

...{
p->nextp=end;
p->prep=end->prep;
end->prep->nextp=p;
end->prep=p;
}
++count;
}

void
Cpcblist::insert_before(Cpcb
*
inpcb,Cpcb
*
nextpcb)

...
{
if( head==nextpcb )

...{
inpcb->nextp=head;
inpcb->prep=NULL;
head->prep=inpcb;
head=head->prep;
++count;
}
else if( end==nextpcb )
push_back(inpcb);
else

...{
inpcb->nextp=nextpcb;
inpcb->prep=nextpcb->prep;
nextpcb->prep->nextp=inpcb;
nextpcb->prep=inpcb;
++count;
}
}

Cpcb
*
Cpcblist::pop(Cpcb
*
p)

...
{
if( p==head )

...{
head=p->nextp;
p->nextp->prep=NULL;
}
else

...{
p->prep->nextp=p->nextp;
p->nextp->prep=p->prep;
}
p->prep=p->nextp=NULL;
--count;
return p;
}

Cpcb
*
Cpcblist::pop_front()

...
{
return pop(head);
}

void
Cpcblist::remove(Cpcb
*
p)

...
{
pop(p);
delete p;
}

//
直接插入排序以减少排序次数
void
Cpcblist::sort()

...
{
Cpcb* ap;
Cpcb* bp=head;
Cpcb* tp;
while( bp!=end && bp->nextp!=end )

...{
ap=bp->nextp;
if( ap->priority>bp->priority && ap!=end )

...{
//if:如果ap的优先级比头结点还大就直接插在头部
//else:判断插入位置,并插入
if( head->priority<ap->priority )

...{
pop(ap);
insert_before(ap,head);
}
else

...{
tp=bp->prep;
while( tp->priority<ap->priority && tp!=head )
tp=tp->prep;
pop(ap);
insert_before(ap,tp->nextp);
}
}
else
bp=bp->nextp;
}
}
shd.h,包含进程队列信息
#ifndef SHD_H
#define SHD_H
#include
"
pcblist.h
"

#define SCHED_PRIO
0
#define SCHED_RR
1

class Crunqueue

...
{
public:
Cpcblist reserve; //后备队列
Cpcblist active; //活动进程队列
Cpcblist hang; //挂起进程队列
Cpcblist over; //完成进程队列
Cpcb* current; //当前运行的进程

private:
Cpcb* randpcb();
void add_to_reserve(Cpcb* p);
void add_to_reday(Cpcb* p);
void add_to_hang(Cpcb* p);
void active_hang(Cpcb* p);
void add_to_over(Cpcb* p);
void out_schedule_prio();
void out_schedule_rr();

void in_schedule();
void in_schedule_prio();
void in_schedule_rr();

private:
int sched_kind; //调度方式,默认为优先级调度
public:
int n_max_run; //规定就绪队列的最大进程数目
int n_process; //全部进程数目
public:
Crunqueue(int n=10);
void out_schedule();
void run(int kind=0);
}
;
#endif
shd.cpp
#include
"
shd.h
"
#include
<
iostream
>
#include
<
iomanip
>
//
for setw()
#include
<
cstdlib
>
//
for srand() and rand()
#include
<
cassert
>
#define ALL_PROCESS
10
using namespace std;

Crunqueue::Crunqueue(
int
n):n_max_run(n),n_process(
0
),sched_kind(
0
)

...
{
for(int i=0;i<ALL_PROCESS;i++)

...{
Cpcb* p=randpcb();
p->pid=i;
add_to_reserve(p);
}
}

Cpcb
*
Crunqueue::randpcb()

...
{
++n_process;
srand(n_process);
Cpcb* p=new Cpcb;
p->pid=n_process;
p->priority=rand()%MAX_PRIO;
p->time_slice=(int)rand()%DEFAULT_TIME_SLICE+1;
return p;
}

void
Crunqueue::add_to_reserve(Cpcb
*
p)

...
{
if( p->state!=TASK_OVER )

...{
reserve.push_back(p);
p->state=TASK_RESERVE;
}
}

void
Crunqueue::add_to_reday(Cpcb
*
p)

...
{
if( active.count<n_max_run )

...{
if( p->state!=TASK_READY )
p->state=TASK_READY;
active.push_back(p);
}
}

void
Crunqueue::add_to_hang(Cpcb
*
p)

...
{
if( p->state==TASK_HANG || p->state==TASK_OVER )
return;
if( p )

...{
active.pop(p);
hang.push_back(p);
p->state=TASK_HANG;
}
schedule();
}

void
Crunqueue::active_hang(Cpcb
*
p)

...
{
if( p->state==TASK_HANG )

...{
hang.pop(p);
active.push_back(p);
in_schedule();
}
}

void
Crunqueue::add_to_over(Cpcb
*
p)

...
{
over.push_back(p);
p->state=TASK_OVER;
out_schedule();
}


/**/
/*按优先级调度--没有采用搜索最高优先级,而用排序是为了与多处理机兼容^_^)*/
void
Crunqueue::out_schedule_prio()

...
{
reserve.sort();
out_schedule_rr();
}

void
Crunqueue::out_schedule_rr()

...
{
int canrun;
//判断后备队列是否超出规定运行线程数,是则按规定道数慢慢来,否则全部上
if( reserve.count>n_max_run-active.count) canrun=n_max_run;
else canrun=reserve.count+active.count;
for(int i=active.count;i<canrun;i++)

...{
add_to_reday(reserve.pop_front());
}
}

void
Crunqueue::in_schedule_prio()

...
{
active.sort();
if( !active.head->run() )

...{
Cpcb* p=active.pop_front();
add_to_over(p);
}
out_schedule();
}

void
Crunqueue::in_schedule_rr()

...
{
while( active.head->run() ); //一直运行,直到该进程结束
Cpcb* p=active.pop_front();
add_to_over(p);
if( !active.count && !hang.count ) return;
out_schedule(); //重新载入进程
}


/**/
/*内调度(俗语低级调度或进程调度):负责就绪队列中进程切换*/
void
Crunqueue::in_schedule()

...
{
if( active.count==0 ) return;
if( SCHED_PRIO==sched_kind )
in_schedule_prio();
else if( SCHED_RR==sched_kind )
in_schedule_rr();
}


/**/
/*外调度(俗语高级调度或作业调度):负责就绪队列线程的供给*/
void
Crunqueue::out_schedule()

...
{
if( reserve.count>0 )

...{
if( SCHED_PRIO==sched_kind )
out_schedule_prio();
else if( SCHED_RR==sched_kind )
out_schedule_rr();
else
return;
}

/**//*外调度是为内调度作准备,循环机制*/
if( active.count || hang.count )
in_schedule();
}


/**/
/*启动调度模拟*/
void
Crunqueue::run(
int
kind)

...
{
sched_kind=kind;
out_schedule();
}

ostream
&
operator
<<
(ostream
&
os,const Cpcb
&
p)

...
{
os<<setw(4)<<p.pid
<<setw(10)<<p.priority
<<setw(12)<<p.time_slice
<<setw(12)<<p.time_ran;
switch(p.state)

...{
case 0:os<<setw(10)<<"reserve"<<endl;break;
case 1:os<<setw(10)<<"reday"<<endl;break;
case 2:os<<setw(10)<<"running"<<endl;break;
case 3:os<<setw(10)<<"waite"<<endl;break;
case 4:os<<setw(10)<<"hang"<<endl;break;
case 5:os<<setw(10)<<"over"<<endl;break;
default:os<<setw(10)<<"unknown"<<endl;
}
return os;
}

ostream
&
operator
<<
(ostream
&
os,const Cpcblist
&
pl)

...
{
//if( sched_kind==SCHED_PRIO )
// cout<<"priotity schedul"<<endl;
//else if( sched_kind==SCHED_RR )
// cout<<"RR schedul"<<endl;
if( pl.count>0 )

...{
os<<setw(4)<<"pid"
<<setw(10)<<"priority"
<<setw(12)<<"time slice"
<<setw(12)<<"time ran"
<<setw(10)<<"state"<<endl;
char oldfill=os.fill('-');
os<<setw(48)<<'-'<<endl;
os.fill(oldfill);
for(Cpcb* p=pl.head;p!=pl.end;p=p->nextp)
os<<*p;
os<<endl;
}
return os;
}

int
main()

...
{
Crunqueue shd(4);
//shd.reserve.sort();
cout<<shd.reserve;
shd.run(0);
cout<<shd.over;
int i;
cin>>i;
}