0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

英创信息技术Linux系统调度简介

英创信息技术 来源:英创信息技术 作者:英创信息技术 2020-02-05 10:31 次阅读

1、综述

Linux作为多任务、多用户的操作系统,其进程/线程调度管理是实现这些特性的关键部分。调度管理决定系统中的众多线程中哪个线程获得执行、什么时候开始执行、执行多久。一个好的调度算法能优化系统资源的使用,提高系统使用效率。

Linux内核中实现了Scheduler Classes,来实现多个调度类(Scheduler class)的协同工作,每个不同的调度类对应不同的类型的线程,而且每个调度类都有自身的优先级,Linux调度管理基础代码会遍历在内核中注册了的调度类,选择高优先级的调度类,然后让此调度类按照自己的调度算法选择下一个执行的线程。Linux系统中常用的几种调度类为SCHED_NORMAL、SCHED_FIFO、SCHED_RR。其中SCHED_NORMAL是用于普通线程的调度类,而SCHED_FIFO和SCHED_RR是用于实时线程的调度类,优先级高于SCHED_NORMAL。内核中区分普通线程与实时线程是根据线程的优先级,实时线程拥有实时优先级(real-time priority),默认取值为0~99,数值越高优先级越高,而普通线程只具有nice值,nice值映射到用户层的取值范围为-20~+19,数值越高优先级越低,默认初始值为0 ,子线程会继承父线程的优先级。对于实时线程,Linux系统会尽量使其调度延时在一个时间期限内,但是不能保证总是如此,不过正常情况下已经可以满足比较严格的时间要求了。下面将分别介绍这些调度类。

2、SCHED_NORMAL

对于SCHED_NORMAL,2.6之前的版本内核中的调度管理程序是根据线程的优先级(nice值)来分配一个固定的时间片(timeslice)给线程,比如nice值0对应于100ms的时间片,而nice值-20对应于5ms时间片,线程在执行过程中进入阻塞状态(I/O操作等引起)或者是执行的时间达到分配的时间片后将会被抢占,而新进入运行态的线程会根据其优先级和可用时间片来决定是否抢占当前正在执行的程序。

2.6之后版本的Linux中SCHED_NORMAL使用的是Linux 内核在2.6.23版本中引入的CFS(Complete Fair Scheduler)调度管理程序。CFS与之前的调度不同的是,线程的优先级与时间片之间并没有一个固定的关系,而是影响该线程在整个系统CPU运行时间中占有比例的一个因素。比如有两个线程,对应的nice值分别为0(普通线程)和+19(低优先级线程),那么普通线程将会占有19/20×100%的CPU时间,而低优先级线程将会占有1/20×100%的CPU时间(具体数值只做举例说明用,Linux内核中的计算出来的数值会不一样)。而如果同时运行的只有两个相同优先级的线程,那么他们分到的CPU时间各是50%。这样每个线程能够分配到的CPU时间占有比例跟系统当前的负载(所有处于运行态的线程数以及各线程的优先级)有关,同一个线程在他本身优先级不变的情况下分到的CPU时间占比会根据系统负载变化而发生变化,也即与时间片没有一个固定的对应关系。

理想情况下CFS对CPU时间占比的衡量是在一个无限小的时间片内计算单个线程执行时间的占比,CFS的目标是所有线程在这个小的时间片周期内执行的时间都是相同的,无限小在现实中显然是不存在的,Linux系统中这个时间片周期是与系统CPU数有关的,默认情况下单核CPU对应6ms,双核CPU对应12ms,8核CPU对应24ms,当线程数增加到很大数量时,CFS会保证每个线程获得最小执行时间, 单核CPU对应0.75ms,双核CPU对应1.5ms,8核CPU对应3ms。在CFS管理下,某个线程运行时如果进入阻塞态(或其他非运行态)或者当前时间片周期内的CPU时间占比达到后将会暂停运行,CFS然后将会选择当前时间片周期内已执行时间最少的运行态线程继续运行。当然CPU时间占比在内核中也是以运行时间衡量的,比如某个单核CPU系统中只有两个相同优先级的线程同时处于运行态,那么CFS将会以6ms为周期来调度所有线程,而每个6ms周期内每个线程分得3ms执行时间,如果某个线程中有I/O操作等其他操作使该线程进入非运行态,CFS将会立即使另外一个线程继续运行,如果两个线程都是基本没有I/O操作等会引起阻塞的操作(比如忙循环),那么线程将会在自己的执行时间结束(本质上是超出CPU时间占比)后被CFS程序调度出当前正在执行的状态,另外一个线程获得CPU资源开始执行。

需要注意的是,进入CFS(或其他调度算法)需要调度事件的产生,调度事件可以是线程自己调用函数显示执行调度,或者线程执行I/O操作等会进入阻塞的操作以及等待的事件发生线程进入运行态等(内核中有固定的调度点),如果一个程序一直处于忙计算(比如忙循环程序),那么就会需要系统软时间中断来产生调度事件从而进入CFS调度判断下一个可执行程序。目前我们的Linux内核普遍配置的系统软时间中断产生的频率为100Hz,也即每10ms产生一次中断,那么系统中只有忙计算类(如忙循环)线程的情况下,只有当系统产生软时间中断时,CFS才会被调用来判断下一个执行的线程并使其占有CPU开始执行,这个现象看起来就好象是Linux调度策略简单的给每个线程分配了10ms的时间片,其实并不是这样。如果系统中同时有忙计算类的线程和经常进行I/O操作类的线程,由于I/O类线程基本处于等待事件的阻塞态中,执行的时间很少,而计算类线程在执行的时间会比较长,如果计算类线程正在执行时,I/O类线程等待的事件发生了,CFS马上就会判断出I/O类线程在之前时间段内执行的时间很少,即已使用的CPU占比与分配给他的相比很小,而计算类线程很有可能已经超过了分配的CPU占比,那么CFS将会马上使I/O类的线程占有CPU开始执行,如此系统总是能及时响应I/O类线程。

3、SCHED_FIFO和SCHED_RR

SCHED_FIFO和SCHED_RR是实时线程使用的调度管理算法。SCHED_FIFO即先进先出,处于相同优先级的实时线程会根据进入运行态的次序依次执行。正在执行的线程会一直执行直到线程阻塞或者其主动调用调度线程放弃执行,处于此调度策略下的线程没有预先分配的时间片,可以永远执行下去。只有拥有更高实时优先级且处于SCHED_RR或者SCHED_FIFO管理下的线程能抢占正在运行的实时线程。

SCHED_RR在SCHED_FIFO的基础上会预先给定线程一个时间片,时间片达到后会使其他相同优先级的线程开始执行。SCHED_RR的时间片轮询机制只对同等实时优先级的线程有效,更高实时优先级的线程总是会抢占正在执行的线程,而低优先级的线程不能抢占高优先级的线程,即使其时间片已到。

实时线程优先级高于所有普通线程,如果有实时线程处于运行态,则系统调度时一定会选择调用实时线程;正在运行的实时线程只会被拥有更高实时优先级的线程抢占。所以在应用中如果需要将某个线程设置为实时线程,则需要用户自己确保该线程不会处于忙执行而完全占用CPU资源,导致其他普通线程没法获得CPU资源而一直被阻塞得不到执行,并且需要合理给予优先级的值,太高有可能会影响重要系统线程的运行。所有用户态线程默认没有实时优先级,都属于普通线程。

4、相关接口函数

Linux系统提供了一系列函数,这些函数可以让用户方便的修改线程/进程的优先级(包括nice值和real-time priority)、以及修改调度策略、设置运行线程的CPU核心等。下面简单介绍一下常用的函数。

(1)修改nice值

int nice ( int incr )

将调用进程的nice值增加incr,incr为负数是提高优先级,为正数时降低优先级。成功返回0。

int setpriority ( int which, id_t who, int prio )

将指定的线程/线程组/用户的nice值设置为prio,whice对应可以取值PRIO_PROCESS、PRIO_PGRP、PRIO_USER,who对应为线程/进程id,组id或者用户id,prio取值范围为-20~19。成功返回0,错误返回-1。

(2)修改real-time priority以及调度策略

int pthread_attr_setschedparam (pthread_attr_t *attr, const struct sched_param *param)

设置调度属性。对于SCHED_FIFO和SCHED_RR,sched_param值包含 int sched_priority,也即real-time priority。下面所有param定义相同。

int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param)

获取调度属性。

int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)

设置调度策略,policy可设置为SCHED_FIFO,SCHED_RR和SCHED_NORMAL。

int pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy)

获取调度策略。

int sched_setparam (pid_t pid, const struct sched_param *param)

设置pid进程的real-time priority,需要pid进程出具SCHED_FIFO或者SCHED_RR调度策略管理下。

int sched_getparam(pid_t pid, struct sched_param *param)

获取real-time priority。

int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param)

设置pid进程的调度策略以及调度属性。

int sched_getscheduler (pid_t pid)

返回pid进程调度策略。

(3)设置线程在哪个CPU核心上运行

int pthread_setaffinity_np (pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset)

int pthread_getaffinity_np (pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset)

int sched_setaffinity (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset)

int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *cpuset)

设置/获取线程可以运行的CPU核心, cpusetsize 可以设置为sizeof(cpu_set_t), cpuset可以用宏CPU_ZERO和CPU_SET设置,函数设置成功后,线程将只会在设置的CPU核心(比如8核CPU可以设置核心1、3、4)上运行,如果cpuset只指定了一个核心,那么线程将只会在此核心上运行。函数出错返回-1,成功返回0。

关于以上函数以及更多与调度相关的函数的详细信息请参考

http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html

http://pubs.opengroup.org/onlinepubs/7908799/xsh/sched.h.html

以及相关函数的Linux man手册和其他相关书籍资料

5、编程示例

下面提供一个示例程序,程序用于展示real-time priority对于进程运行时调度管理的影响,程序运行于ESM6802(双核)工控主板上。程序会在主进程中使用fork新建一个进程,然后调用sched_setscheduler设置子进程的实时优先级为30, 同时设置其使用SCHED_FIFO调度策略,而主进程只有nice值为0 的普通优先级。两个进程主体部分相同,均为在忙循环中置高然后置低一位GPIO的输出电平,通过示波器观察GPIO的状态,如果进程一直执行,则会看到连续的周期较固定的方波,而如果进程被其他进程抢占,则会看到GPIO的状态很长时间没有发生变化,以此来展示实时优先级对系统调度的影响。程序部分代码如下:

int gpio = GPIO6;

structsched_param rt_param = {

.sched_priority = 30 }; //实时优先级30

child_pid = fork(); //创建子进程

if(child_pid!=0) //child_pid不等于0为主进程,等于0为子进程

{

if( -1 == sched_setscheduler ( child_pid, SCHED_FIFO, &rt_param ) )

printf("sched_setscheduler failed\n");

//设置子进程实时优先级以及调度算法

printf ( "child_pid = %d\n", child_pid );

gpio = GPIO5; //主进程和子进程操作不同的GPIO

}

printf("Driver esm6800_gpio test\n");

fd = open("/dev/esm6800_gpio", O_RDWR);

printf("open file = %d\n", fd);

rc = GPIO_OutEnable(fd, 0xff); //set GPIO as output

if(rc < 0)

{

printf("GPIO_OutEnable::failed %d\n", rc);

returnrc;

}

for(;;) //无限循环

{

//忙循环中置高然后置低gpio输出电平

rc = GPIO_OutSet(fd, gpio); //使GPIO输出高电平

if(rc < 0)

{

printf("GPIO_OutSet::failed %d\n", rc);

returnrc;

}

rc = GPIO_OutClear(fd, gpio); //使GPIO输出低电平

if(rc < 0)

{

printf("GPIO_OutClear::failed %d\n", rc);

returnrc;

}

}

使用示波器查看到的GPIO状态如下图,其中黄色信号为主进程操作的GPIO5,蓝色信号为有实时优先级的子进程操作的GPIO6:

可以看出蓝色信号代表的拥有实时优先级的进程一直处于执行当中,没有被其他低优先级的进程抢占,而黄色信号代表的普通优先级的程序gpio状态切换有很明显的中断,也即其他进程被抢占而中断执行。此结果与第一节介绍的Linux调度策略一致:实时线程只会被拥有更高实时优先级的线程抢占,处于SCHED_FIFO下的实时线程可以无限执行。

用户在实际编程中应该仔细规划自己的程序,合理利用系统调度接口函数,来优化自己程序的执行效果,同时避免错误的使用导致系统正常运行。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206738
  • 嵌入式主板
    +关注

    关注

    7

    文章

    6064

    浏览量

    34614
收藏 人收藏

    评论

    相关推荐

    Linux是做什么用的?

    ,进行软件开发、系统管理和网络管理等工作。 5、学习和教育:Linux是一个开源的操作系统,提供了大量的学习资源和教育机会。许多学校和教育机构使用Linux来教授计算机科学和
    发表于 04-28 15:40

    兆芯正引入Linux首选内核调度技术,优化性能

    近期,兆芯工程团队亦在致力于将首选内核调度技术引进Linux系统中。他们试图通过提议的Linux内核补丁,利用已有的ACPI功能来辨别每个核
    的头像 发表于 12-29 14:30 214次阅读
    兆芯正引入<b class='flag-5'>Linux</b>首选内核<b class='flag-5'>调度</b><b class='flag-5'>技术</b>,优化性能

    阐述量子信息技术的研究现状与未来

    20世纪 80 年代, 科学家将量子力学应用到信息领域, 从而诞生了量子信息技术, 诸如量子计算机、量子密码、量子传感等. 这些技术的运行规律遵从量子力学, 因此不仅其原理是量子力学, 器件本身
    发表于 11-22 11:40 481次阅读
    阐述量子<b class='flag-5'>信息技术</b>的研究现状与未来

    信息技术是干什么?

    广播电子技术信息技术
    橙群微电子
    发布于 :2023年09月22日 09:17:48

    现场总线技术及其应用

    计算机网络、通信与控制技术的发展,导致自动化系统的深刻变革。信息技术正迅速渗透到生产现场的设备层,覆盖从生产车间到企业管理经营的各个方面,沟通从原料供应﹑生产制造到生产调度﹑资源规划乃
    发表于 09-20 07:20

    基于RFID技术CFS智能仓库系统的解决方案

    系统是在现有CFS仓库管理中引入RFID技术,对CFS仓库中的入库、出库、调拨、移库移位、库存盘点等各个作业环节进行自动化的数据采集,在仓库作业区域实施无线网络覆盖,实现叉车和工作人员调度信息
    发表于 09-19 08:20

    再次登榜|亿达科创入选“2023年度软件和信息技术服务竞争力百强企业”

    8月31日,在第二十五届中国国际软件博览会上,中国电子信息行业联合会发布了“2023年度软件和信息技术服务竞争力百强企业”榜单。 亿达科创凭借在企业规模、经营业绩、技术创新等方面的综合能力强
    的头像 发表于 09-12 16:29 513次阅读

    集成电路是现代电子信息技术的基础

    集成电路是现代电子信息技术的基础 随着科技的不断发展,集成电路技术已成为现代电子信息技术的基础之一。它的应用范围已经涉及到电子、通信、计算机、军事等行业,已经为人们的生活和工作带来了极大的便利
    的头像 发表于 08-29 16:25 1275次阅读

    信息技术促使轨道交通全面升级

    有别于传统的铁公路系统,新型基础建设强调的是将新一代的信息技术纳入基建领域,在未来的交通系统中,智能化、信息化的轨道交通系统网络,搭配5G等
    的头像 发表于 08-21 11:11 480次阅读

    2023年国家级高职学校信息技术教师能力培训会圆满举行

    2023年国家级高职学校信息技术教师能力培训会圆满举行
    的头像 发表于 07-31 22:56 389次阅读
    2023年国家级高职学校<b class='flag-5'>信息技术</b>教师能力培训会圆满举行

    中科驭数成为证券基金行业信息技术应用创新知识库首批合作厂商!

    7月20日,证券基金行业信息技术应用 创新中心与中国信息通信研究院携手合作,正式上线了行业信息技术应用创新知识库, 旨在做好对行业信息技术应用创新工作的支撑,加强产业侧和行业机构之间的
    的头像 发表于 07-21 18:50 322次阅读
    中科驭数成为证券基金行业<b class='flag-5'>信息技术</b>应用创新知识库首批合作厂商!

    2023年中海达星推官系列直播再度启航,与您一起探讨空间信息技术

    信息技术
    中海达
    发布于 :2023年06月21日 11:45:49

    中科曙光参建国内首个信息技术领域产教融合共同体

    “新一代信息技术产业产教融合共同体”在京成立(简称“共同体”)。**该共同体是由中国电子学会联合国内信息技术行业重点职业院校与重点企业成立的。首批成员单位的11家新一代信息技术领域领先职业院校校长,以及9家行业知名企业领导共同出
    的头像 发表于 06-13 12:38 440次阅读

    权威榜单发布!“2022-2023信息技术应用创新榜”隆重揭晓

    2023年5月8日,由信息化观察网、信息技术应用创新榜组委会组织发起的“2022-2023信息技术应用创新榜”评审结果正式公示。本次榜单征集旨在全面展示信创发展最新成果,遴选出信创细分领域创新
    的头像 发表于 05-09 09:40 849次阅读

    Linux内核进程管理与调度:策略优化与实践分析

    今天给大家上点硬货,关于Linux的进程管理和调度是学习和理解Linux的必学知识。为协调多个进程 "同时" 运行,现代操作系统通常使用进程优先级这一基本手段。每个进程都有
    发表于 05-08 09:42 603次阅读
    <b class='flag-5'>Linux</b>内核进程管理与<b class='flag-5'>调度</b>:策略优化与实践分析