c语言sscanf函数的用法是什么
338
2022-11-01
一文了解Linux调度器开放给用户空间的接口
二、nice函数
nice函数用来修改调用进程的nice value,其接口定义如下:
#include int nice(int inc);
为了方便说明该接口的作用,我们还是举实际的例子说明。程序调用nice(3),则将当前进程的nice value增加3,这也就是意味着该进程的优先级降低3个level(提升nice value也就是对别人更加nice,自己的优先级就会低)。如果程序调用nice(-5),则将当前进程的nice value减去5,这也就是意味着该进程的优先级提升5个level。当调用错误的时候返回-1,调用成功会稍微有一些歧义。POSIX标准规定了nice函数返回新的nice value,但是linux的系统调用和c库都是采用了操作成功返回0的方式。这样的处理方式使得在调用nice函数的时候无法得到当前的优先级,如果想要得到当前优先级,需要调用getpriority函数,我们在下一小节描述。
三、getpriority/setpriority函数
从上节的描述中,我们了解到了nice的函数的限制,例如只能修改自己的nice value,无法获取当前的nice value值等,为此我们给出加强版本的nice接口,也就是getpriority/setpriority函数了。getpriority/setpriority函数定义如下:
#include #include
int getpriority(int which, int who); int setpriority(int which, int who, int prio);
getpriority/setpriority功能比较强大,能处理多种请求,不同的请求通过which和who这两个参数来制定。当which等于PRIO_PROCESS的时候,who需要传入一个process id的参数,getpriority将返回指定进程的nice value。当which等于PRIO_PGRP的时候,who需要传入一个process group id的参数,此时getpriority将返回指定进程组中优先级最高的那个(BTW,nice value是最小的)。当which等于PRIO_USER的时候,who需要user id的信息,这时候,getpriority将返回属于该user的所有进程中nice value最小的那个。who等于0说明要get或者set的对象是当前进程(或者当前进程组,或者当前的user)。
setpriority类似与nice,当然功能要强那么一点点,因为它可以接收PRIO_PROCESS,PRIO_PGRP或者PRIO_USER参数用来设定一组进程的nice value。setpriority的返回值和其他函数类似,0表示成功,-1表示操作失败,不过getpriority就稍微有一点绕了。作为linux程序员,我们都知道的nice value是[-20, 19],如果getpriority返回这个范围,那么这里的-1优先级就有点尴尬了,因为一般的linux c库接口函数返回-1表示调用错误,我们是如何区分-1调用错误的返回还是优先级-1的返回值呢?getpriority是少数返回-1也是有可能正确的接口函数:在调用getpriority之前,我们需要首先将errno清零,调用getpriority之后,如果返回-1,我们需要看看errno是否还是保持0值,如果是,那么说明返回的是优先级-1,否则说明发生了错误。
四、操作rt priority的接口
好的调度策略依赖于对进程的分类,有一类进程是大家都灰常的熟悉了就是普通进程,使用时间片轮转算法的那些进程。当然这类进程还可以细分,例如运算密集型进程(SCHED_BATCH,调度器最好不要太经常的唤醒这种进程),例如idle类进程(SCHED_IDLE),idle类进程优先级非常低,也就是说如果系统有其他事情要处理就去干别的事情(调度其他进程执行),实在没有活干了,再考虑IDLE类型的进程。不论哪一种普通进程,其优先级使用nice value这样一个调度参数来描述就OK了。
介绍到这里,是时候总结一下了:进程优先级有两个范围,一个是nice value,用前两个小节的API来set或者get。另外一个优先级是rt priority,完全碾压nice value这种优先级,操作rt priority的接口就在这一小节描述。
#include
int sched_getscheduler(pid_t pid);
int sched_setparam(pid_t pid, const struct sched_param *param); int sched_getparam(pid_t pid, struct sched_param *param);
sched_get_priority_max和sched_get_priority_min分别返回了指定调度策略的最大和最小的rt priority,不同的操作系统实现不同的优先级数量。在linux中,实时进程(SCHED_FIFO和SCHED_RR)的rt priority共计99个level,最小是1,最大是99。对于其他的调度策略,这些函数返回0。
sched_getscheduler函数可以获取指定进程的scheduling policy(如果pid等于0,那么是获取调用进程的调度策略)。sched_setscheduler函数是用来设定指定进程的scheduling policy,对于实时进程,该接口函数还可以设定rt priority。如果设定进程的调度策略是非实时的调度策略的时候(例如SCHED_NORMAL),那么param参数是没有意义的,其sched_priority成员必须设定为0。sched_setparam/sched_getparam非常简单,大家自己看man page好了。
五、一统江湖的接口
看起来前面小节描述的API已经够用了,然而,故事并未结束。经过前面关于调度接口的讨论,基本上我们对调度器的行为也已经有了了解:调度器就是按照优先级(指rt priority)来工作,优先级高的永远是优先调度。范围落在[1,99]的rt priority是实时进程,而rt priority等于0的是普通进程。对于普通进程,调度器还要根据nice value(这个也曾经被称为优先级,不要和rt priority弄混了)来进行调整。用户空间的进程可以通过各种前面描述的接口API来修改调度策略、nice value以及rt priority。一切看上去已经完美,CFS类型的调度器处理普通的运算密集形(例如编译内核)和用户交互形的应用(例如vi编辑文件)。如果有应用有实时需求,可以考虑让rt类型的调度器来运筹帷幄。但是,如何混合了一些realtime的应用以及有一些timing要求的应用的时候,SCHED_FIFO和SCHED_RR并不能解决问题,因为在这种调度策略下,高优先级的任务会永远的delay低优先级的任务,如果低优先级的任务有一些timing的需求,这时候,你根本控制不了调度延迟时间。
为了解决上一节中描述的问题,一类新的进程被定义出来,这类进程的优先级比实时进程和普通进程的优先级都要高,这类进行有自己的特点,参考下图:
虽然deadline进程优先级高于其他两类进程,但是用“优先级”来描述这类进程当然是不合理的,应该使用下面的三个参数来描述:
(1)周期时间(上图中的period)
(2)deadline时间(上图中的relative deadline)
(3)一次调度周期内分配多少的cpu时间(上图中的comp. time)
至此,估计您也已经发现,前面描述的接口其实都是不适合设定这些参数的,因此,GNU/linux操作系统中增加了下面的接口API:
#include
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags); int sched_getattr(pid_t pid, const struct sched_attr *attr, unsigned int size, unsigned int flags);
attr这个参数的数据类型是struct sched_attr,这个数据结构囊括了一切你想要的关于调度的控制参数:policy,nice value,rt priority,period,deadline等等。用这个接口可以完成所有前面几个小节描述API能完成的任务,唯一的不好的地方就是这个接口是linux特有的,不是posix标准,是否应用这个接口就是见仁见智了。更细节的知识这里就不描述了,大家还是参考man page好了。
六、其他
上面描述的接口API都是和调度器参数相关,其实Linux调度器还有两类接口。一个是sched_getaffinity和sched_setaffinity,用于操作一个线程的CPU affinity。另外一个接口是sched_yield,该接口可以让出CPU资源,让Linux调度器选择一个合适的线程执行。这些接口很简单,大家仔细学习就OK了。
参考文档:
1、POSIX标准2008
2、linux下的各种man page
3、linux 4.4.6内核源代码
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~