在任务的概念当中由于运行的需求,我们常常需要给任务一定分类,在系统里面就诞生出来所谓线程优先级 实时线程 单位时间相应能力强,里面拥有1-99个静态优先级,数字越大,优先级越高(所谓的优先级指的经过特殊的处理,我们可以让某个人物能够在系统中被更优先的响应,从而分出的从高到低的级别),需要有管理员权限才能启动实时线程
特点:
实时线程分99个静态优先级,数字越大,优先级越高 高优先级的实时线程会完全抢占低优先级实时线程的资源(指令运行资源) 在实时线程当中支持抢占调度策略跟轮询调度策略 拥有抢占所有实时线程运行资源的能力 必须拥有超级用户权限才能够运行
非实时线程 单位时间中,并没有过分的去在乎响应能力的一个线程,里面只有一个静态优先级0,也就是在非实时线程中,它是没有静态优先级的概念的,他的所有的执行过程都是由系统自动分配的
特点:
非实时线程只有一个静态优先级,所以同时非实时线程的任务无法抢占他人的资源 在非实时线程当中只支持其他调度策略(自动适配的,系统分配的调度策略) 不拥有抢占所有运行资源的能力 支持动态优先级系统自适应,从-20到19的动态优先级(nice值)
线程中支持三种调度策略:
1.抢占式调度策略,在同一静态优先级的情况下,抢占调度策略的线程一旦运行到便会一直抢占CPU资源,而其他同一优先级的只能一直等到这个抢占式调度策略的线程退出才能被运行到(非实时线程会有一小部分资源分配到)2.轮询式调度策略,在同一静态优先级的情况下,大家一起合理瓜分时间片,不会一直抢占CPU资源(非实时线程会有一小部分资源分配到)3.其他普通式调度策略,只能作用于非实时线程,由系统自动分配时间片,并且根据运行状态自动分配动态优先级 注意点:
抢占式调度策略跟轮询式调度策略只能在实时线程中被设置,也就是静态优先级1-99的区域内设置,普通非实时线程不能设置
pthread_attr_setinheritsched 设置线程是否继承父线程调度策略
#include
int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);
函数功能:
设置线程是否继承父线程调度策略
参数:
attr:线程属性结构体地址 inheritsched:是否继承父线程的调度策略 PTHREAD_EXPLICIT_SCHED:不继承,只有不继承父线程的调度策略才可以设置线程的调度策略 PTHREAD_INHERIT_SCHED:继承父进程的调度策略
返回值:
成功的情况下,返回值为0,失败返回非0值,errno不会被设置
pthread_attr_setschedpolicy 设置线程的调度策略
#include
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
函数功能:
设置线程的调度策略属性
参数:
attr:线程属性结构体地址policy:调度策略
- SCHED_FIFO:抢占式调度,同一优先级中,一旦运行到设置了这个参数的线程CPU将会一直被该线程所占领,不会分配资源给其他实时线程,会分配一点资源给非实时线程
- SCHED_RR:轮询式调度,同一优先级总,遇到这个设置的线程,将会给其运行一段时间后,又继续给下一个人运行(相当于大家平均运行),会分配一点资源给非实时线程上面的两种是针对静态优先级1-99的实时线程才能设置的。
- SCHED_OTHER:其他普通的调度策略,仅能设置与0静态优先级,也就是非实时线程,让这条线程成为一个由系统去自动根据动态优先级分配资源的任务。
返回值:
成功的情况下,返回值为0,失败返回非0值,errno不会被设置 pthread_attr_setschedparam 设置静态优先级
函数功能:
- 设置静态优先级
参数:
- attr:线程属性结构体地址
- param:优先级结构体,里面只有元素sched_priority,用来登记线程的静态优先级的值。
struct sched_param {
int sched_priority; /* Scheduling priority */
}
返回值:
成功的情况下,返回值为0,失败返回非0值,errno不会被设置
获取静态优先级的最小值与最大值的函数 获取最小值:
sched_get_priority_min(SCHED_FIFO); 获取最大值:
sched_get_priority_max(SCHED_FIFO); 例程:测试分离属性以及栈大小
例程:测试分离属性以及栈大小#define _GNU_SOURCE //注意这个宏定义不要漏了
#include
#include
#include
#include
#include
void *new_thread(void *arg)
{
int retval;
pthread_attr_t myattr;
size_t stack_size;
/*
//这个函数使用后,时灵时不灵,不建议使用
retval = pthread_detach(pthread_self());
if(retval != 0)
{
fprintf(stderr, "设置分离失败:%s\n", strerror(retval));
}
*/
//获取本线程的属性存放到myattr这个变量中
pthread_getattr_np(pthread_self(), &myattr);
//获取线程栈的大小
pthread_attr_getstacksize(&myattr, &stack_size);
printf("stack size = %ld\n", stack_size);
while(1)
{
sleep(1);
printf("in thread\n");
}
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_attr_t attr;
//线程属性初始化
pthread_attr_init(&attr);
//设置线程的属性成为完全分离状态,再也不能用pthread_join来等待这条线程
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED);
//设置线程的栈大小
pthread_attr_setstacksize(&attr, 16*1024*1024);
//取消行程,后面篇章详细描写
pthread_create(&tid, &attr, new_thread, NULL);
//线程属性销毁
pthread_attr_destroy(&attr);
//线程的属性成为完全分离状态,再也不能用pthread_join来等待这条线程
//pthread_join(tid, NULL);//等待线程退出
return 0;
}
例程:测试优先级
注意:只有在CPU只有一个内核才看得出效果
同时改变优先级还需要系统超级用户权限(没有超级用户权限,不给你执行,所以一般情况下很少会设置优先级)
虚拟机设置单核如下>>虚拟机设置=>硬件=>处理器 此处可以设置CPU数量和核数
#include
#include
#include
#include
#include
void *start_routine(void *arg)
{
int i, j;
while(1)
{
fprintf(stderr, "%c ", *(char *)arg);
for(i=0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?