最近实验课老多。不过实验课当然比理论课好玩多了。关于实践和理论,我想说一句,只懂理论不懂实践,相当于左膀右避缺了一样。
废话少说,步入正题。老师给了第一个版本的代码,是基于时间片轮转来进行线程调度的,我们的任务就是把调度算法改成基于优先级调度的程序。
首先,我们要在struct TCB里面添加一个用于表示优先级的字段:int pri;
struct TCB{
unsigned char *stack;
unsigned int ss;
unsigned int sp;
int state;
int pri;
char name[10];
}tcb[NTCB];
其次,初始化tcb[0], tcb[1], tcb[2]里面的pri值,tcb[0].pri 在main函数里面初始化为0; tcb[1].pri、tcb[2].pri在InitTCB里面初始化为50,100(这两个数值随便你们改,但不能为0)。
tcb[1].pri = 10;
tcb[2].pri = 5;
tcb[0].pri = 0;
另外,更改调度算法,即更改Find()函数,我们改为如下:
int Find()
{
int i,max_pri,index;
i = max_pri = index = 0;
for( ; i < NTCB; i ++)
{
if(tcb[i].state != FINISHED && tcb[i].pri > max_pri) // 如果某个线程执行完成,它的状态就会被over()设置成FINISHED
{
max_pri = tcb[i].pri;
index = i; // 保存最大优先级的下标
}
}
return index; //返回最大优先级的下标,
}
最后,就是特别坑的一行代码,在new_int8里面,要注释掉
if (i == current ) return;
为何要注释掉呢?你的线程若还没有执行完,就被中断调度了,那Find()返回的值是不是和current相等呢,答案是肯定的。那后面的timecount就不能被清零,那就下次中断来临时,if(timecount!=TIMESLIP)就永远不可能为真,线程就不能被调度了,懂?
最后 的最后,上修改过后的代码:
#include
#include
int current;
long timecount;
#define NTCB 3
#define FINISHED 0
#define RUNNING 1
#define READY 2
#define BLOCKED 3
#define TIMEINT 0x08
#define TIMESLIP 5
#define STACKLEN 1024
struct TCB{
unsigned char *stack;
unsigned int ss;
unsigned int sp;
int state;
int pri;
char name[10];
}tcb[NTCB];
void interrupt (*old_int8)(void);
void interrupt new_int8(void);
void interrupt test_int8(void);
void over(void);
#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06
char far *indos_ptr=0;
char far *crit_err_ptr=0;
int DosBusy(void);
void InitInDos(void);
void InitInDos(void)
{
union REGS regs;
struct SREGS segregs;
regs.h.ah=GET_INDOS;
intdosx(®s, ®s, &segregs);
indos_ptr=MK_FP(segregs.es, regs.x.bx);
if(_osmajor<3)
crit_err_ptr=indos_ptr+1;
else if(_osmajor==3&&_osminor==0)
crit_err_ptr=indos_ptr-1;
else
{
regs.x.ax=GET_CRIT_ERR;
intdosx(®s, ®s, &segregs);
crit_err_ptr=MK_FP(segregs.ds, regs.x.si);
}
}
int DosBusy(void)
{
if(indos_ptr&&crit_err_ptr)
return(*indos_ptr||*crit_err_ptr);
else
return -1;
}
typedef void (far *funcptr)(void);
int create(char *name, funcptr func, int stlen);
void p1( )
{
long i, j, k;
for(i=0; i<40; i++)
{
putchar('a');
for(j=0; j<1000; j++)
for(k=0; k<20000; k++);
}
}
void p2( )
{
long i, j, k;
for(i=0; i<20; i++)
{
putchar('b');
for(j=0; j<1000; j++)
for(k=0;k<20000; k++);
}
}
int Find()
{
int i,max_pri,index;
i = max_pri = index = 0;
for( ; i < NTCB; i ++)
{
if(tcb[i].state != FINISHED && tcb[i].pri > max_pri)
{
max_pri = tcb[i].pri;
index = i;
}
}
return index;
}
void interrupt swtch() /* 其他原因CPU调度 */
{
int i;
if(tcb[current].state!=FINISHED
&¤t!=0) /* 当前线程还没结束 */
return;
i=Find();
if(i<0)
return;
disable();
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY; /* 放入就绪队列中 */
_SS=tcb[i].ss;
_SP=tcb[i].sp; /* 保存现场 */
tcb[i].state=RUNNING;
current=i;
enable();
}
void over()
{
if(tcb[current].state==RUNNING)
{
disable();
tcb[current].state=FINISHED;
strcpy(tcb[current].name,NULL);
free(tcb[current].stack);
enable();
}
swtch();
}
void InitTcb()
{
unsigned int *tmp=0;
//for thread 1
tcb[1].state=READY;
tcb[1].pri = 10;
// strcpy(tcb[1].name, "p1");
tcb[1].stack=(unsigned char *)malloc(STACKLEN);
memset(tcb[1].stack, 0xff, STACKLEN);
tmp=(unsigned int *)(tcb[1].stack+STACKLEN-2);
*tmp=FP_SEG(over);
*(tmp-1)=FP_OFF(over);
*(tmp-2)=0x200;
*(tmp-3)=FP_SEG(p1);
*(tmp-4)=FP_OFF(p1);
*(tmp-9)=_ES;
*(tmp-10)=_DS;
tcb[1].ss=FP_SEG(tmp-13);
tcb[1].sp=FP_OFF(tmp-13);
//for thread 2
tcb[2].state=READY;
tcb[2].pri = 5;
// strcpy(tcb[2].name, "p2");
tcb[2].stack=(unsigned char *)malloc(STACKLEN);
memset(tcb[2].stack, 0xff, STACKLEN);
tmp=(unsigned int *)(tcb[2].stack+STACKLEN-2);
*tmp=FP_SEG(over);
*(tmp-1)=FP_OFF(over);
*(tmp-2)=0x0200;
*(tmp-3)=FP_SEG(p2);
*(tmp-4)=FP_OFF(p2);
*(tmp-9)=_ES;
*(tmp-10)=_DS;
tcb[2].ss=FP_SEG(tmp-13);
tcb[2].sp=FP_OFF(tmp-13);
}
void interrupt new_int8(void)
{
int i;
(*old_int8)();
timecount++;
if(timecount!=TIMESLIP)
return;
else
{
if(DosBusy())
return;
else
{
disable();
// asm CLI
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;
i=Find();
//if(i==current)
// return;
_SS=tcb[i].ss;
_SP=tcb[i].sp;
tcb[i].state=RUNNING;
timecount=0;
current=i;
enable();
// asm STI
}
}
}
void tcb_state()
{
int i;
for(i=0; i
运行结果p1,p2输出为aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbb