博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
posix多线程有感--线程高级编程(线程调度以及优先级设置)
阅读量:6824 次
发布时间:2019-06-26

本文共 3978 字,大约阅读时间需要 13 分钟。

当在属性对象中设置调度策略或优先级时,必须同时设置inheritsched属性(即继承属性设置为:PTHREAD_EXPLICIT_SCHED)。
 

linux内核的三种调度方法:

  • SCHED_OTHER 分时调度策略
  • SCHED_FIFO实时调度策略,先到先服务
  • SCHED_RR实时调度策略,时间片轮转

实时进程将得到优先调用,实时进程根据实时优先级决定调度权值,分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度。

SHCED_RR和SCHED_FIFO的不同:当采用SHCED_RR策略的进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。

SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。

 

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); 来创建线程,但是如何设置线程的优先级呢? 在讨论这个问题的时候,我们先要确定当前线程使用的调度策略,posix提供了 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

函数来获取所使用的调度策略,它们是:SCHED_FIFO, SCHED_RR 和 SCHED_OTHER。

我们可以使用: int sched_get_priority_max(int policy); int sched_get_priority_min(int policy); 来获取线程线程可是设置的最大和最小的优先级值,如果调用成功就返回最大和最小的优先级值,否则返回-1。 从我现在运行的linux系统中,我使用下列程序(程序见附录)获取了对应三种调度策略中的最大和最小优先级: policy = SCHED_OTHER Show current configuration of priority max_priority = 0 min_priority = 0 Show SCHED_FIFO of priority max_priority = 99 min_priority = 1 Show SCHED_RR of priority max_priority = 99 min_priority = 1 Show priority of current thread priority = 0 Set thread policy Set SCHED_FIFO policy policy = SCHED_FIFO Set SCHED_RR policy policy = SCHED_RR Restore current policy policy = SCHED_OTHER

我们可以看到SCHED_OTHER是不支持优先级使用的,而SCHED_FIFO和SCHED_RR支持优先级的使用,他们分别为1和99,数值越大优先级越高。 从上面的结果我们可以看出,如果程序控制线程的优先级,一般是用pthread_attr_getschedpolicy来获取系统使用的调度策略,如果是SCHED_OTHER的话,表明当前策略不支持线程优先级的使用,否则可以。当然所设定的优先级范围必须在最大和最小值之间。我们可以通过sched_get_priority_max和sched_get_priority_min来获取。

#include    
#include
#include
#include
#include
#include
void * thr_fun(void *arg){ int policy, ret; struct sched_param param; //获取线程调度参数 ret = pthread_getschedparam(pthread_self(), &policy, &param); if(ret!=0) { printf("pthread_getschedparam %s\n", strerror(ret) ); exit(1); } if (policy == SCHED_FIFO) { printf("policy:SCHED_FIFO\n"); } else if (policy == SCHED_OTHER) { printf("policy:SCHED_OTHER\n"); } else if (policy == SCHED_RR) { printf("policy:SCHED_RR\n"); } printf("param: %d\n", param.sched_priority); printf("pthread getpid = %d\n",getpid()); long long i; while (1) { i++; i *= 2; } pthread_exit(NULL);}int main(int argc,char *argv[]){ int ret; pthread_t tid; pthread_attr_t attr; int policy, inher; struct sched_param param; //初始化线程属性 pthread_attr_init(&attr); //获取继承的调度策略 ret = pthread_attr_getinheritsched(&attr, &inher); if (ret!=0) { printf("pthread_attr_getinheritsched %s\n", strerror(ret)); exit(1); } if (inher == PTHREAD_EXPLICIT_SCHED) { printf("PTHREAD_EXPLICIT_SCHED\n"); } else if (inher == PTHREAD_INHERIT_SCHED) { printf("PTHREAD_INHERIT_SCHED\n"); inher = PTHREAD_EXPLICIT_SCHED; } //设置继承的调度策略 //必需设置inher的属性为 PTHREAD_EXPLICIT_SCHED,否则设置线程的优先级会被忽略 ret = pthread_attr_setinheritsched(&attr, inher); if (ret!=0) { printf("pthread_attr_setinheritsched %s\n", strerror(ret)); exit(1); } sleep(1); policy = SCHED_FIFO;//在Ubuntu10.04上需要root权限 //设置线程调度策略 ret = pthread_attr_setschedpolicy(&attr, policy); if (ret!=0) { printf(" pthread_attr_setschedpolicy%s\n", strerror(ret)); exit(1); } param.sched_priority = 3; //设置调度参数 ret = pthread_attr_setschedparam(&attr, &param); if (ret!=0) { printf(" pthread_attr_setschedparam %s\n", strerror(ret)); exit(1); } //创建线程 ret = pthread_create(&tid, &attr, thr_fun, NULL); if (ret!=0) { printf("pthread_create %s\n", strerror(ret)); exit(1); } printf("main getpid = %d\n",getpid()); sleep(5); while (1) { printf("hello world\n"); printf("getpid = %d\n",getpid()); } pthread_join(tid, NULL); pthread_exit(NULL);}

root@# top -H
Priority 3 FIFO [99-100-3=-4]???
 
 

409# cat sched  

实时进程优先级:  

prio = MAX_RT_PRIO(100)– 1 – rt_priority(3)= 96;

policy:

0 SCHED_OTHER 
1.SCHED_FIFO 
2.SCHED_RR

转载于:https://www.cnblogs.com/hehehaha/archive/2013/05/10/6332822.html

你可能感兴趣的文章
【Linux】了解服务器的情况
查看>>
解决Spring配置文件不显示design和source, namespace 问题
查看>>
Efficiently traversing InnoDB B+Trees with the page directory--slot
查看>>
算法笔记_191:历届试题 大臣的旅费(Java)
查看>>
乐为物联网平台初步体验(1)
查看>>
利用ArcGIS水文分析工具提取河网
查看>>
看58同城9月招聘季 大数据显示蓝领薪酬更高
查看>>
跳台阶
查看>>
Android API学习 SoundPool 和 MediaPlayer
查看>>
郁闷的一天
查看>>
祖宗十八代的称谓
查看>>
如何配置Hyper-V的虚拟机通过主机网络上网 (NAT)
查看>>
Linux make语法
查看>>
淘宝下单高并发解决方案
查看>>
[华为机试练习题]55.最大公约数 & 多个数的最大公约数
查看>>
文章标题
查看>>
对js原型对象的拓展和原型对象的重指向的区别的研究
查看>>
将数值四舍五入后格式化,带有千分位
查看>>
Atitit.反编译apk android源码以及防止反编译apk
查看>>
EF增删改查操作
查看>>