pthread调度策略,优先级和竞争范围
实时调度:操作系统在有限的时间内提供特定水平的服务能力。受限制的响应时间不一定是块的反应,意味着可预知的响应速度。如果系统定义_POSIX_THRAED_PRIORITY_SCHEDULING,它为线程指派实时调度优先级提供支持。支持_POSIX_THRAED_PRIORITY_SCHEDULING的系统必须提供至少包括成员seched_priority的struct sched_param结构体的定义,seched_priority的标准策略是SCHED_FIFO和SCHED_RR使用的唯一参数。
影响实时调度:调度策略,参数,竞争范围和分配域
实时调度在某种程度上不一定很快,实时调度可能会变得很慢,因为它包含了更多抢占检查的开销特别是在一台多处理机上
固定优先级调度可能会导致优先级倒置,优先级倒置——低优先级线程阻塞高优先级线程运行,他是调度和同步之间一个不干净的相互作用的结果。调用要求一个线程运行,但是同步要求运用另行的线程,所以两个优先级好像颠倒。如:一个低优先级线程获互斥资源,并且被一个随后在同样资源阻塞的高优先级线程抢占时,优先级发生倒置,在只有两个线程被允许运行时,低优先级线程被先执行,然后释放互斥量,如果在他们之间有第三个线程准备好时,他能阻塞低优先级线程运行,因为低优先级线程拥有高优先级线程拥有的互斥量,中间优先级线程阻止了高优先级线程的执行
优先级调度不完全可移植。如:使用系统竞争范围时,你的线程可以直接与操作系统内核线程相竞争,提高自定义线程的优先级可能会阻止内核I/O驱动在系统上的一些工作
确实需要使用优先级调度时(一般避免使用,因为相比解决问题,他会引起更多的问题),应记住:
- 进程竞争范围比系统竞争范围“更好”,因为你不会阻止其他进程或内核中的某个线程运行
- SCHED_RR比SCHED_FIFO“更好”,并且具有可移植性,因为SCHED_RR线程将在具有相同优先级线程共享可用处理器时间间隔中被抢占
- 对SCHED_FIFO和SCHED_RR而言,低优先级比高优先级更好,因为能更少的妨碍另外重要的东西
//1.设置的最高和最低优先级,policy: 可以取三个值(SCHED_FIFO、SCHED_RR、SCHED_OTHER)
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy); //2.设置和获取优先级
//param是struct sched_param类型的指针,它仅仅包含一个成员变sched_priority,指明所要设置的静态线程优先级。
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
param.sched_priority = ; //设置优先级
struct sched_param
{
int __sched_priority; // 所要设定的线程优先级
}; //3.改变策略(静态改变策略和设置优先级)
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int policy); //4.继承调度属性,该属性控制了你创建的线程从创建线程那继承调度信息,schedpolicy和schedparam显示设置调度信息
//我手动设置了调度策略或优先级时,必须显示的设置线程调度策略的inheritsched属性,因为pthread没有为inheritsched设置默认值
//所以在改变了调度策略或优先级时必须总是设置该属性。
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);
/*
第一个函数中inheritsched的取值为:PTHREAD_INHERIT_SCHED 或者 PTHREAD_EXPLICIT_SCHED。
前者为继承创建线程的调度策略和优先级,后者指定不继承调度策略和优先级,而是使用自己设置的调度策略和优先级。
无论何时,当你需要控制一个线程的调度策略或优先级时,必须将inheritsched属性设置为PTHREAD_EXPLICIT_SCHED。
*/ //5.置正在运行的线程的调度策略和优先级(动态设置线程的调度策略和优先级)
//前面的那些函数只能通过线程的属性对象 pthread_attr_t 来设置线程的调度策略和优先级,不能够直接设置正在运行的线程的调度策略和优先级
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
//在成功完成之后返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,pthread_setschedparam() 函数将失败并返回
//相应的值--EINVAL所设置属性的值无效。ENOTSUP--尝试将该属性设置为不受支持的值。
//int pthread_setschedparam:thread参数所指向的线程不存在
//int pthread_getschedparam:1.参数policy或同参数policy关联的调度参数之一无效;
//2.数policy或调度参数之一的值不被支持;
//3.调用线程没有适当的权限来设置指定线程的调度参数或策略
//4.参数thread指向的线程不存在;5.实现不允许应用程序将参数改动为特定的值
- SCHED_OTHER(是Linux默认的分时调度策略):它是默认的线程分时调度策略,所有的线程的优先级别都是0(不使用sched_param结构体的sched_priority成员),如果系统使用这种调度策略,程序将无法设置线程的优先级。这种调度策略也是抢占式的,当高优先级的线程准备运行的时候,当前线程将被抢占并进入等待队列。这种调度策略仅仅决定线程在可运行线程队列中的具有相同优先级的线程的运行次序。(使用此方式的代码不可移植)
- SCHED_FIFO:它是一种实时的先进先出调用策略,且只能在超级用户下运行。这种调用策略仅仅被使用于优先级大于0的线程。使用SCHED_FIFO的线程运行到有更高级的线程准备好或者愿意自己阻塞为止;当有一个线程准备好时,除非有平等或更高级的线程准备好,否则他将很快运行自己。如果有若干相同优先级的线程等待执行,然而最早执行的线程无终止或者阻塞动作,那么其他线程是无法执行的,除非当前线程调用如pthread_yield之类的函数,所以在使用SCHED_FIFO的时候要小心处理相同级别线程的动作。
- SCHED_RR:若有一个此类的线程运行超过一定的时间没有阻塞,而另外的SCHED_RR或SCHED_FIFO策略相同优先级的线程准备好时,运行的线程将被枪占意识准备好的线程运行。
- 对于 SCHED_OTHER 策略,sched_priority 只能为 0。对于 SCHED_FIFO,SCHED_RR 策略,sched_priority 从 1 到 99。
- 调度策略和优先级是分开来描述的。前者使用预定义的SCHED_RR、SCHED_FIFO、SCHED_OTHER,后者是通过结果体struct sched_param给出的。
- 这些设置调度策略和优先级的函数操作的对象是线程的属性pthread_attr_t,而不是直接来操作线程的调度策略和优先级的。函数的第一个参数都是pthread_attr_t。
- 当pthread_setschedparam函数的参数 policy == SCHED_RR 或者 SCHED_FIFO 时,程序必须要在超级用户下运行
- pthread_setschedparam 函数改变在运行线程的调度策略和优先级肯定就不用调用函数来设置inheritsched属性了:pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED); 因为该函数设置的对象是pthread_attr_t
- 当在对象属性中设置调度策略或优先级时,必须同时设置inheritsched属性
- 改变线程属性中调度策略和参数时是两个操作,修改调度策略和修改参数
- 不能独立于线程的参数来修改一个可执行线程的调度策略,为了调度正确操作,参略和参数一定是一致的,每个调度策略有一个优先级的唯一范围,并且一个线程不能对一个对当前调度策略而言无效的优先级执行。
竞争范围和分配域
int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
/*
返回值:若是成功返回0,否则返回错误的编号
形 参:
attr 指向一个线程属性的指针
scope 返回线程的作用域
*/
//指定了线程与谁竞争资源
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
/*
返回值:若是成功返回0,否则返回错误的编号
attr 指向一个线程属性的指针
guardsize 线程的作用域,可以取如下值
PTHREAD_SCOPE_SYSTEM 与系统中所有进程中线程竞争
PTHREAD_SCOPE_PROCESS 与当前进程中的其他线程竞争
*/
竞争范围:描述了线程为处理资源而竞争的方式,系统竞争范围意味着线程与进程之外的线程竞争处理器资源,一个进程内的高优先级系统竞争范围线程能阻止其他进程内的系统竞争范围运行。竞争范围指的是仅仅在同一进程内相互竞争。
分配域:系统内线程可以为其他竞争的处理器的集合。一个系统可以有一个以上的分配域,每个包含一个以上的处理器,在一个单处理器的处理机上,各个分配域可以包含从一个处理器到系统中所有的处理器。(没有实现该接口)
- 竞争范围内的线程可以共享一个核实体
- 系统竞争范围线程之间的环境切换通常要求至少一次内核调用
- 竞争范围在优先级调度上没有给你真正的控制——高优先级的线程可以优先于进程内的其他线程运行
- 当一个线程被分配超过一个处理机的分配域时,应用程序不能完全依靠可预知的调度行为;如:高优先级和低优先级可以同时运行,调度程序不允许因为一个高优先级的线程正在运行而是处理及闲置,单处理机行为在一台多处理机上没什么意思。
核实体
线程:调用pthread_create创建的一个线程,类行为pthread_t的一个标识符代表,使用pthreads接口可控制
处理机:物理硬件
核实体:线程和处理机间的一层附加抽象,可能是一个传统的UNIX进程。
线程与核实体的交互方式:多对一(用户级),一对一(内核级),多对少
pthread调度策略,优先级和竞争范围的更多相关文章
- QNX 线程 调度策略 优先级 时钟频率 同步
/* * barrier1.c */ #include <stdio.h>#include <unistd.h>#include <stdlib.h>#includ ...
- pthread信号
信号是典型的异步事件.内核在某个信号出现时有三种处理方式: 忽略信号,除了SIGKILL和SIGSTOP信号不能忽略外,其他大部分信号都可以被忽略: 捕捉信号,也就是在信号发生时调用一个用户函数,注意 ...
- 多线程 用户级线程和内核级线程 from C++多核高级编程
转 http://book.51cto.com/art/201006/206946.htm 6.1.1 用户级线程和内核级线程 2010-06-21 20:37 齐宁/董泽惠 译 清华大学出版社 字号 ...
- 浅析Linux线程调度
在Linux中,线程是由进程来实现,线程就是轻量级进程( lightweight process ),因此在Linux中,线程的调度是按照进程的调度方式来进行调度的,也就是说线程是调度单元.Linux ...
- java线程安全
(一).java并发之原子性与可见性 原子性 原子是世界上的最小单位,具有不可分割性.比如 a=0:(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作.再比如:a+ ...
- 【Hadoop学习】HDFS中的集中化缓存管理
Hadoop版本:2.6.0 本文系从官方文档翻译而来,转载请尊重译者的工作,注明以下链接: http://www.cnblogs.com/zhangningbo/p/4146398.html 概述 ...
- 多线程:深入Thread.sleep
一直都说,Threed.sleep是不会释放锁,而wait是释放锁的(对象锁),现理论上来分析一下. 由于CPU分配的每个线程的时间片极为短暂(一般为几十毫秒),所以,CPU通过不停地切换线程执行,这 ...
- CAN通讯的总结
1.CAN通讯有套国际标准,套协议版本号,种故障状态,种数据帧类型,种总线错误类型. 2.CAN的国际标准有两种ISO11898和ISO11519. 3.CAN2.0协议分为A版和B版两种,A版协议仅 ...
- ADB——命令大全
基本语法 基本语法 adb [-d|-e|-s <serialNumber>] <command> # serialNumber表示设备序列号,也可以是ip地址 # 如果只有一 ...
随机推荐
- python 封装时间常用操作方法-time,datetime
封装脚本: #encoding=utf-8import timefrom datetime import timedelta,date def date_time_chinese(): prin ...
- OpenResty api 网关
1,Orange网关 Orange是一个基于OpenResty的API网关.除Nginx的基本功能外,它还可用于API监控.访问控制(鉴权.WAF).流量筛选.访问限速.AB测试.动态分流等.它有以下 ...
- tslib移植中环境变量编辑
(1)将/usr/local/tslib下的所有文件复制到移植系统文件中/usr/local(2)编辑移植系统中/etc/profile添加触摸屏支持内容:在/etc/profile文件中设置tsli ...
- AVAudioFoundation(6):时间和媒体表示
本文转自:AVAudioFoundation(6):时间和媒体表示 | www.samirchen.com 本文主要内容来自 AVFoundation Programming Guide. 基于时间的 ...
- Django学习笔记之ORM多表操作
创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关 ...
- java maven 操作 收集的一些命令
maven打包: mvn clean package -Dmaven.test.skip=true 运行jar: java -jar target/spring-boot-scheduler-1.0. ...
- Jenkins报错Error cloning remote repo 'origin'
Jenkins控制台输出报错 输出ERROR: Error cloning remote repo 'origin' 这行报错只能说明是git有问题,其他没什么有用的信息. 浏览器中Ctrl+F查找E ...
- hive row_number等窗口分析函数
一.排序&去重分析 row_number() over(partititon by col1 order by col2) as rn 结果:1,2,3,4 rank() over(parti ...
- uva-10491-经典问题
https://vjudge.net/problem/UVA-10491 有a个门后是牛,b个门后是车,一开始随机选一个门,然后主持人会打开c(c<a)个为牛的门,之后可以选择换门(这里要求总是 ...
- Digitalocean+DNSPod搭建Meteor.js博客Telescope.js
1. 什么是Meteor.js 基于Node.js的一个快速开发平台. 简言之,Node.js>Meteor.js 对等于Ruby>Ruby on Rails的关系. 官网:http:// ...