Linux内核的三种调度策略.docx

上传人:b****1 文档编号:151304 上传时间:2023-04-28 格式:DOCX 页数:13 大小:18.67KB
下载 相关 举报
Linux内核的三种调度策略.docx_第1页
第1页 / 共13页
Linux内核的三种调度策略.docx_第2页
第2页 / 共13页
Linux内核的三种调度策略.docx_第3页
第3页 / 共13页
Linux内核的三种调度策略.docx_第4页
第4页 / 共13页
Linux内核的三种调度策略.docx_第5页
第5页 / 共13页
Linux内核的三种调度策略.docx_第6页
第6页 / 共13页
Linux内核的三种调度策略.docx_第7页
第7页 / 共13页
Linux内核的三种调度策略.docx_第8页
第8页 / 共13页
Linux内核的三种调度策略.docx_第9页
第9页 / 共13页
Linux内核的三种调度策略.docx_第10页
第10页 / 共13页
Linux内核的三种调度策略.docx_第11页
第11页 / 共13页
Linux内核的三种调度策略.docx_第12页
第12页 / 共13页
Linux内核的三种调度策略.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Linux内核的三种调度策略.docx

《Linux内核的三种调度策略.docx》由会员分享,可在线阅读,更多相关《Linux内核的三种调度策略.docx(13页珍藏版)》请在冰点文库上搜索。

Linux内核的三种调度策略.docx

Linux内核的三种调度策略

Linux内核的三种调度策略:

  1,SCHED_OTHER分时调度策略,

2,SCHED_FIFO实时调度策略,先到先服务。

一旦占用cpu则一直运行。

一直运行直到有更高优先级任务到达或自己放弃

3,SCHED_RR实时调度策略,时间片轮转。

当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。

放在队列尾保证了所有具有相同优先级的RR任务的调度公平

Linux线程优先级设置

首先,可以通过以下两个函数来获得线程可以设置的最高和最低优先级,函数中的策略即上述三种策略的宏定义:

  intsched_get_priority_max(intpolicy);

  intsched_get_priority_min(intpolicy);

 SCHED_OTHER是不支持优先级使用的,而SCHED_FIFO和SCHED_RR支持优先级的使用,他们分别为1和99,数值越大优先级越高。

设置和获取优先级通过以下两个函数

intpthread_attr_setschedparam(pthread_attr_t*attr,conststructsched_param*param);

  intpthread_attr_getschedparam(constpthread_attr_t*attr,structsched_param*param);

param.sched_priority=51;//设置优先级

系统创建线程时,默认的线程是SCHED_OTHER。

所以如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

intpthread_attr_setschedpolicy(pthread_attr_t*attr,intpolicy);

上面的param使用了下面的这个数据结构:

structsched_param

{

int__sched_priority;//所要设定的线程优先级

};

我们可以通过下面的测试程序来说明,我们自己使用的系统的支持的优先级:

#include

#include

#include

#include

staticintget_thread_policy(pthread_attr_t*attr)

{

intpolicy;

intrs=pthread_attr_getschedpolicy(attr,&policy);

assert(rs==0);

switch(policy)

{

caseSCHED_FIFO:

printf("policy=SCHED_FIFO\n");

break;

caseSCHED_RR:

printf("policy=SCHED_RR");

break;

caseSCHED_OTHER:

printf("policy=SCHED_OTHER\n");

break;

default:

printf("policy=UNKNOWN\n");

break;

}

returnpolicy;

}

staticvoidshow_thread_priority(pthread_attr_t*attr,intpolicy)

{

intpriority=sched_get_priority_max(policy);

assert(priority!

=-1);

printf("max_priority=%d\n",priority);

priority=sched_get_priority_min(policy);

assert(priority!

=-1);

printf("min_priority=%d\n",priority);

}

staticintget_thread_priority(pthread_attr_t*attr)

{

structsched_paramparam;

intrs=pthread_attr_getschedparam(attr,¶m);

assert(rs==0);

printf("priority=%d",param.__sched_priority);

returnparam.__sched_priority;

}

staticvoidset_thread_policy(pthread_attr_t*attr,intpolicy)

{

intrs=pthread_attr_setschedpolicy(attr,policy);

assert(rs==0);

get_thread_policy(attr);

}

intmain(void)

{

pthread_attr_tattr;

structsched_paramsched;

intrs;

rs=pthread_attr_init(&attr);

assert(rs==0);

intpolicy=get_thread_policy(&attr);

printf("Showcurrentconfigurationofpriority\n");

show_thread_priority(&attr,policy);

printf("showSCHED_FIFOofpriority\n");

show_thread_priority(&attr,SCHED_FIFO);

printf("showSCHED_RRofpriority\n");

show_thread_priority(&attr,SCHED_RR);

printf("showpriorityofcurrentthread\n");

intpriority=get_thread_priority(&attr);

printf("Setthreadpolicy\n");

printf("setSCHED_FIFOpolicy\n");

set_thread_policy(&attr,SCHED_FIFO);

printf("setSCHED_RRpolicy\n");

set_thread_policy(&attr,SCHED_RR);

printf("Restorecurrentpolicy\n");

set_thread_policy(&attr,policy);

rs=pthread_attr_destroy(&attr);

assert(rs==0);

return0;

}

下面是测试程序的运行结果:

policy=SCHED_OTHER

Showcurrentconfigurationofpriority

max_priority=0

min_priority=0

showSCHED_FIFOofpriority

max_priority=99

min_priority=1

showSCHED_RRofpriority

max_priority=99

min_priority=1

showpriorityofcurrentthread

priority=0Setthreadpolicy

setSCHED_FIFOpolicy

policy=SCHED_FIFO

setSCHED_RRpolicy

policy=SCHED_RRRestorecurrentpolicy

policy=SCHED_OTHER

 

Linux线程调度策略与优先级

(二)

上一篇文章介绍了Linux下的调度策略和优先级,在Ubuntu09.10上的一些特性,这里测试一下其中的两种特性,SCHED_OTHER和SCHED_RR,还有就是优先级的问题,是不是能够保证,高优先级的线程,就可以保证先运行。

下面的这个测试程序,创建了三个线程,默认创建的线程的调度策略是SCHED_OTHER,其余的两个线程的调度策略设置成SCHED_RR。

我的Linux的内核版本是2.6.31。

SCHED_RR是根据时间片来确定线程的调度。

时间片用完了,不管这个线程的优先级有多高都不会在运行,而是进入就绪队列中,等待下一个时间片的到了,那这个时间片到底要持续多长时间?

在《深入理解Linux内核》中的第七章进程调度中,是这样描诉的,Linux采取单凭经验的方法,即选择尽可能长、同时能保持良好相应时间的一个时间片。

这里也没有给出一个具体的时间来,可能会根据不同的CPU来定,还有就是多CPU的情况。

#include

#include

#include

#include

voidThread1()

{

sleep

(1);

inti,j;

intpolicy;

structsched_paramparam;

pthread_getschedparam(pthread_self(),&policy,¶m);

if(policy==SCHED_OTHER)

printf("SCHED_OTHER\n");

if(policy==SCHED_RR);

printf("SCHED_RR1\n");

if(policy==SCHED_FIFO)

printf("SCHED_FIFO\n");

for(i=1;i<10;i++)

{

for(j=1;j<5000000;j++)

{

}

printf("thread1\n");

}

printf("Pthread1exit\n");

}

voidThread2()

{

sleep

(1);

inti,j,m;

intpolicy;

structsched_paramparam;

pthread_getschedparam(pthread_self(),&policy,¶m);

if(policy==SCHED_OTHER)

printf("SCHED_OTHER\n");

if(policy==SCHED_RR);

printf("SCHED_RR\n");

if(policy==SCHED_FIFO)

printf("SCHED_FIFO\n");

for(i=1;i<10;i++)

{

for(j=1;j<5000000;j++)

{

}

printf("thread2\n");

}

printf("Pthread2exit\n");

}

voidThread3()

{

sleep

(1);

inti,j;

intpolicy;

structsched_paramparam;

pthread_getschedparam(pthread_self(),&policy,¶m);

if(policy==SCHED_OTHER)

printf("SCHED_OTHER\n");

if(policy==SCHED_RR)

printf("SCHED_RR\n");

if(policy==SCHED_FIFO)

printf("SCHED_FIFO\n");

for(i=1;i<10;i++)

{

for(j=1;j<5000000;j++)

{

}

printf("thread3\n");

}

printf("Pthread3exit\n");

}

intmain()

{

inti;

i=getuid();

if(i==0)

printf("Thecurrentuserisroot\n");

else

printf("Thecurrentuserisnotroot\n");

pthread_tppid1,ppid2,ppid3;

structsched_paramparam;

pthread_attr_tattr,attr1,attr2;

pthread_attr_init(&attr1);

pthread_attr_init(&attr);

pthread_attr_init(&attr2);

param.sched_priority=51;

pthread_attr_setschedpolicy(&attr2,SCHED_RR);

pthread_attr_setschedparam(&attr2,¶m);

pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);//要使优先级其作用必须要有这句话

param.sched_priority=21;

pthread_attr_setschedpolicy(&attr1,SCHED_RR);

pthread_attr_setschedparam(&attr1,¶m);

pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);

pthread_create(&ppid3,&attr,(void*)Thread3,NULL);

pthread_create(&ppid2,&attr1,(void*)Thread2,NULL);

pthread_create(&ppid1,&attr2,(void*)Thread1,NULL);

pthread_join(ppid3,NULL);

pthread_join(ppid2,NULL);

pthread_join(ppid1,NULL);

pthread_attr_destroy(&attr2);

pthread_attr_destroy(&attr1);

return0;

}

 

下面是该程序的其中之一的运行结果:

sudo./prio_test

Thecurrentuserisroot

SCHED_OTHER

SCHED_RR

SCHED_RR1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

Pthread1exit

thread2

thread2

thread2

thread2

thread2

thread2

thread2

thread2

thread2

Pthread2exit

thread3

thread3

thread3

thread3

thread3

thread3

thread3

thread3

thread3

Pthread3exit

这里我们可以看到,由于线程3的调度策略是SCHED_OTHER,而线程2的调度策略是SCHED_RR,所以,在Thread3中,线程3被线程1,线程2给抢占了。

由于线程1的优先级大于线程2的优先级,所以,在线程1以先于线程2运行,不过,这里线程2有一部分代码还是先于线程1运行了。

我原以为,只要线程的优先级高,就会一定先运行,其实,这样的理解是片面的,特别是在SMP的PC机上更会增加其不确定性。

其实,普通进程的调度,是CPU根据进程优先级算出时间片,这样并不能一定保证高优先级的进程一定先运行,只不过和优先级低的进程相比,通常优先级较高的进程获得的CPU时间片会更长而已。

其实,如果要想保证一个线程运行完在运行另一个线程的话,就要使用多线程的同步技术,信号量,条件变量等方法。

而不是绝对依靠优先级的高低,来保证。

不过,从运行的结果上,我们可以看到,调度策略为SCHED_RR的线程1,线程2确实抢占了调度策略为SCHED_OTHER的线程3。

这个是可以理解的,由于SCHER_RR是实时调度策略。

只有在下述事件之一发生时,实时进程才会被另外一个进程取代。

(1)进程被另外一个具有更高实时优先级的实时进程抢占。

(2)进程执行了阻塞操作并进入睡眠

(3)进程停止(处于TASK_STOPPED或TASK_TRACED状态)或被杀死。

(4)进程通过调用系统调用sched_yield(),自愿放弃CPU。

(5)进程基于时间片轮转的实时进程(SCHED_RR),而且用完了它的时间片。

基于时间片轮转的实时进程是,不是真正的改变进程的优先级,而是改变进程的基本时间片的长度。

所以基于时间片轮转的进程调度,并不能保证高优先级的进程先运行。

下面是另一种运行结果:

sudo./prio_test

Thecurrentuserisroot

SCHED_OTHER

SCHED_RR1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

thread1

Pthread1exit

SCHED_RR

thread2

thread2

thread2

thread2

thread2

thread2

thread2

thread2

thread2

Pthread2exit

thread3

thread3

thread3

thread3

thread3

thread3

thread3

thread3

thread3

Pthread3exit

可以看出并没有每一次都保证高优先级的线程先运行。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 其它考试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2