重庆大学操作系统实验二线程及其调度Word下载.docx
- 文档编号:17375573
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:15
- 大小:135.21KB
重庆大学操作系统实验二线程及其调度Word下载.docx
《重庆大学操作系统实验二线程及其调度Word下载.docx》由会员分享,可在线阅读,更多相关《重庆大学操作系统实验二线程及其调度Word下载.docx(15页珍藏版)》请在冰豆网上搜索。
掌握线程的创建
掌握线程的调度
a)静态优先级调度
b)动态优先级调度
二、实验原理(软件设计文档)
系统调用接口,线程相关函数:
•Step1:
定义线程函数
voidtsk_foo(void*pv)
{
printf("
Thisistaskfoowithtid=%d\r\n“,task_getid());
task_exit(0);
}
•Step2:
申请用户栈
unsignedchar*stack_foo;
stack_foo=(unsignedchar*)malloc(1024*1024);
–线程退出后,才能把用户栈用free释放掉!
•Step3:
创建线程
inttid_foo;
tid_foo=task_create(stack_foo+1024*1024,tsk_foo,(void*)0);
三、使用仪器、材料(软硬件开发环境)
Notepad++
expenv
四、实验步骤(实现的过程)
随机生成3组非负整数列表,创建3个线程,分别用3种不同的排序算法(插入,冒泡,选择)对列表进行排序
三线程:
voidtsk_foo_line1(void*pv)
{
intm;
inti;
intarry[50];
srand(time(NULL));
for(i=0;
i<
50;
i++){
m=random()%200;
if(m<
0){m=0-m;
}
draw(i*10,0,0+m);
arry[i]=m;
sort_m(arry,50,0);
voidtsk_foo_line2(void*pv)
draw(i*10,345,345+m);
sort_x(arry,50,345);
voidtsk_foo_line3(void*pv)
draw(i*10,690,690+m);
sort_c(arry,50,690);
voiddraw(intx,inty1,inty2){
for(i=y1;
y2;
i++)
setPixel(i,x,RGB(255,255,255));
voidresetBK(intx,inty1,inty2){
setPixel(i,x,RGB(0,0,0));
三排序:
冒泡
voidsort_m(int*arry,intn,intl){
inti,j,tem;
intt=500/n;
n;
for(j=0;
j<
n-i-1;
j++){
if(*(arry+j)>
*(arry+j+1)){
resetBK(j*t,l,l+*(arry+j));
resetBK(j*t+t,l,l+*(arry+j+1));
tem=*(arry+j);
*(arry+j)=*(arry+j+1);
*(arry+j+1)=tem;
draw(j*t,l,l+*(arry+j));
draw(j*t+t,l,l+*(arry+j+1));
}
插入
voidsort_c(int*arry,intn,intl){
inti,j,key;
for(j=n-2;
j>
=0;
j--){
key=*(arry+j);
i=j+1;
resetBK(j*t,l,l+key);
while(i<
n&
&
*(arry+i)<
key){
*(arry+i-1)=*(arry+i);
draw(i*t-t,l,l+*(arry+i-1));
i=i+1;
*(arry+i-1)=key;
draw(i*t-t,l,l+key);
选择
voidsort_x(int*arry,intn,intl){
inti=0,j=0,lowindex=0;
lowindex=i;
for(j=n-1;
j>
i;
j--)
if(arry[j]<
arry[lowindex])
lowindex=j;
if(lowindex!
=i)
{
resetBK(i*t,l,l+*(arry+i));
resetBK(lowindex*t,l,l+*(arry+lowindex));
inttemp=arry[i];
arry[i]=arry[lowindex];
arry[lowindex]=temp;
draw(i*t,l,l+*(arry+i));
draw(lowindex*t,l,l+*(arry+lowindex));
线程控制块tcb中增加nice属性,在函数sys_task_create中初始化nice=0
/*
系统调用getpriority的执行函数
获取当前线程的优先级
*/
intsys_getpriority(inttid)
if(tid==0)returng_task_running->
nice+NZERO;
//获取当前线程的nice值
uint32_tflags;
structtcb*tsk;
save_flags_cli(flags);
tsk=get_task(tid);
restore_flags(flags);
returntsk->
//获取线程的nice值
系统调用setpriority的执行函数
调整当前线程的优先级
//把线程tid的nice设为(prio-NZERO)
intsys_setpriority(inttid,intprio)
if(tid==0){
save_flags_cli(flags);
g_task_running->
nice=prio-20;
//设置当前线程的nice值
restore_flags(flags);
return0;
//if(tsk==NULL)return-1;
if(prio<
0)prio=0;
//prio必须在[0,2*NZERO-1]
if(prio>
40)prio=40;
//用save_flags_cli/restore_flags保护
tsk->
//设置线程的nice值
return0;
把这两个个函数做成系统调用,分别是getpriority(inttid),setpriority(inttid,intprio)
静态调度schedule:
voidschedule(){
structtcb*select=g_task_head;
structtcb*my_select=g_task_running;
while(select!
=NULL){
if((select->
tid!
=0)&
(select->
state==TASK_STATE_READY))
{
//if(my_select==NULL){my_select=select;
continue;
if(select->
nice<
=my_select->
nice)//选择等待队列里的线程优先级高的
my_select=select;
if(my_select->
tid==0){//跳过task0运行
}
}
select=select->
next;
if(my_select==g_task_running){
if(g_task_running->
state==TASK_STATE_READY)
return;
my_select=task0;
//仅当没有其他可运行的线程时,才能调度
g_resched=0;
switch_to(my_select);
线程控制块tcb中
增加estcpu属性,在函数sys_task_create中初始化estcpu=0;
增加priority属性,在函数sys_task_create中初始化priority=0;
timer.c中增加全局变量g_load_avg:
表示系统的平均负荷
用浮点(float-point)表示g_load_avg和estcpu:
精度高,效率低
动态调度schedule:
voidschedule()
structtcb*select=g_task_head;
while(select!
=NULL)
{
select->
priority=127-fixedpt_toint(fixedpt_div(select->
estcpu,fixedpt_fromint(4)))-select->
nice*2;
//计算所有线程的priority
select=select->
//动态优先级
select=g_task_head;
state==TASK_STATE_READY)){
if(my_select->
priority<
select->
priority)
my_select=select;
//选择等待队列里的线程优先级高的
elseif(my_select->
tid==0)
if(my_select->
my_select=task0;
printk("
0x%d->
0x%d\r\n"
(g_task_running==NULL)?
-1:
g_task_running->
tid,select->
tid);
timer.c中添加如下
g_task_running->
estcpu=fixedpt_add(g_task_running->
estcpu,FIXEDPT_ONE);
//计算线程使用CPU时间estcpu
if(g_timer_ticks%HZ==0){//每隔一秒计算一次
intnready=0;
//表示处于就绪状态的线程个数
structtcb*my_select=g_task_head;
intnice;
//g_task_running->
nice;
//my_select=g_task_head;
fixedptratio;
while(my_select!
state==TASK_STATE_READY)nready++;
nice=my_select->
ratio=fixedpt_mul(FIXEDPT_TWO,g_load_avg);
//每秒钟为所有线程(运行、就绪和等待)更新一次
ratio=fixedpt_div(ratio,fixedpt_add(ratio,FIXEDPT_ONE));
my_select->
estcpu=fixedpt_add(fixedpt_mul(ratio,my_select->
estcpu),
fixedpt_fromint(nice));
my_select=my_select->
fixedptr59_60=fixedpt_div(fixedpt_fromint(59),fixedpt_fromint(60));
//计算系统的平均负荷g_load_avg
fixedptr01_60=fixedpt_div(FIXEDPT_ONE,fixedpt_fromint(60));
g_load_avg=fixedpt_add(fixedpt_mul(r59_60,g_load_avg),
fixedpt_mul(r01_60,fixedpt_fromint(nready)));
主函数:
intmode=0x0118;
initGraphics(mode);
inty=0;
for(y=0;
y<
g_mib.YResolution;
y++){
setPixel(g_mib.XResolution/3,y,RGB(0,125,125));
setPixel(g_mib.XResolution/3*2,y,RGB(0,125,125));
int*pcode_exit;
//申请用户栈
unsignedchar*stack_foo1=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo2=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo3=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo4=(unsignedchar*)malloc(1024*1024);
inttid_foo1,tid_foo2,tid_foo3;
setpriority(0,8);
//创建冒泡排序线程函数1
tid_foo1=task_create(stack_foo1+1024*1024,tsk_foo_line1,(void*)0);
setpriority(tid_foo1,1);
//创建选择排序线程函数2
tid_foo2=task_create(stack_foo2+1024*1024,tsk_foo_line2,(void*)0);
setpriority(tid_foo2,10);
//创建插入排序线程函数3
tid_foo3=task_create(stack_foo3+1024*1024,tsk_foo_line3,(void*)0);
setpriority(tid_foo3,8);
setpriority(0,35);
//用户栈释放
task_wait(tid_foo1,pcode_exit);
free(stack_foo1);
task_wait(tid_foo2,pcode_exit);
free(stack_foo2);
task_wait(tid_foo3,pcode_exit);
free(stack_foo3);
五、实验结果及分析(实现的效果,包括屏幕截图、系统总体运行情况和测试情况等)
静态优先级:
动态优先级:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 重庆大学 操作系统 实验 线程 及其 调度
![提示](https://static.bdocx.com/images/bang_tan.gif)