重庆大学操作系统实验二线程及其调度.docx
- 文档编号:4449091
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:15
- 大小:135.21KB
重庆大学操作系统实验二线程及其调度.docx
《重庆大学操作系统实验二线程及其调度.docx》由会员分享,可在线阅读,更多相关《重庆大学操作系统实验二线程及其调度.docx(15页珍藏版)》请在冰豆网上搜索。
重庆大学操作系统实验二线程及其调度
重庆大学
学生实验报告
实验课程名称操作系统原理
开课实验室重庆大学DS1501
学院软件工程年级2013专业班
学生姓名学号
开课时间2015至2016学年第一学期
总成绩
教师签名
洪明坚
重庆大学软件学院制
《操作系统原理》实验报告
开课实验室:
DS15012016年1月6日
学院
软件学院
年级、专业、班
姓名
成绩
课程
名称
操作系统原理
实验项目
名称
线程及其调度
指导教师
教师评语
教师签名:
年月日
一、实验目的(软件需求文档)
掌握线程的创建
掌握线程的调度
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);
task_exit(0);
}
voidtsk_foo_line2(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,345,345+m);
arry[i]=m;
}
sort_x(arry,50,345);
task_exit(0);
}
voidtsk_foo_line3(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,690,690+m);
arry[i]=m;
}
sort_c(arry,50,690);
task_exit(0);
}
voiddraw(intx,inty1,inty2){
inti;
for(i=y1;i setPixel(i,x,RGB(255,255,255)); } voidresetBK(intx,inty1,inty2){ inti; for(i=y1;i setPixel(i,x,RGB(0,0,0)); } 三排序: 冒泡 voidsort_m(int*arry,intn,intl){ inti,j,tem; intt=500/n; for(i=0;i for(j=0;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; intt=500/n; for(j=n-2;j>=0;j--){ key=*(arry+j);i=j+1; resetBK(j*t,l,l+key); while(i *(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; intt=500/n; for(i=0;i lowindex=i; for(j=n-1;j>i;j--) if(arry[j] 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+NZERO;//获取线程的nice值 } /* 系统调用setpriority的执行函数 调整当前线程的优先级 */ //把线程tid的nice设为(prio-NZERO) intsys_setpriority(inttid,intprio) { uint32_tflags;structtcb*tsk; 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(flags); tsk=get_task(tid);//用save_flags_cli/restore_flags保护 restore_flags(flags); tsk->nice=prio-20;//设置线程的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运行 my_select=select; } } 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; structtcb*my_select=g_task_running; while(select! =NULL) { select->priority=127-fixedpt_toint(fixedpt_div(select->estcpu,fixedpt_fromint(4)))-select->nice*2;//计算所有线程的priority select=select->next; } //动态优先级 select=g_task_head; while(select! =NULL){ if((select->tid! =0)&&(select->state==TASK_STATE_READY)){ if(my_select->priority { my_select=select;//选择等待队列里的线程优先级高的 } elseif(my_select->tid==0) { my_select=select; } } select=select->next; } if(my_select==g_task_running){ if(my_select->state==TASK_STATE_READY) return; my_select=task0; } printk("0x%d->0x%d\r\n",(g_task_running==NULL)? -1: g_task_running->tid,select->tid); g_resched=0; switch_to(my_select); } 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! =NULL){ if(my_select->state==TASK_STATE_READY)nready++; nice=my_select->nice; 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->next; } 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 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文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 重庆大学 操作系统 实验 线程 及其 调度