sio调度器源码分析的简单介绍
本文目录一览:
技术问题
Code maturity level options
代码成熟度选项
Prompt for development and/or incomplete code/drivers
显示尚在开发中或尚未完成的代码与驱动.除非你是测试人员或者开发者,否则请勿选择
General setup
常规设置
Local version - append to kernel release
在内核版本后面加上自定义的版本字符串(小于64字符),可以用"uname -a"命令看到
Automatically append version information to the version string
自动在版本字符串后面添加版本信息,编译时需要有perl以及git仓库支持
Support for paging of anonymous memory (swap)
使用交换分区或者交换文件来做为虚拟内存
System V IPC
System V进程间通信(IPC)支持,许多程序需要这个功能.必选,除非你知道自己在做什么
IPC Namespaces
IPC命名空间支持,不确定可以不选
POSIX Message Queues
POSIX消息队列,这是POSIX IPC中的一部分
BSD Process Accounting
将进程的统计信息写入文件的用户级系统调用,主要包括进程的创建时间/创建者/内存占用等信息
BSD Process Accounting version 3 file format
使用新的第三版文件格式,可以包含每个进程的PID和其父进程的PID,但是不兼容老版本的文件格式
Export task/process statistics through netlink
通过netlink接口向用户空间导出任务/进程的统计信息,与BSD Process Accounting的不同之处在于这些统计信息在整个任务/进程生存期都是可用的
Enable per-task delay accounting
在统计信息中包含进程等候系统资源(cpu,IO同步,内存交换等)所花费的时间
UTS Namespaces
UTS名字空间支持,不确定可以不选
Auditing support
审计支持,某些内核模块(例如SELinux)需要它,只有同时选择其子项才能对系统调用进行审计
Enable system-call auditing support
支持对系统调用的审计
Kernel .config support
把内核的配置信息编译进内核中,以后可以通过scripts/extract-ikconfig脚本来提取这些信息
Enable access to .config through /proc/config.gz
允许通过/proc/config.gz访问内核的配置信息
Cpuset support
只有含有大量CPU(大于16个)的SMP系统或NUMA(非一致内存访问)系统才需要它
Kernel-user space relay support (formerly relayfs)
在某些文件系统上(比如debugfs)提供从内核空间向用户空间传递大量数据的接口
Initramfs source file(s)
initrd已经被initramfs取代,如果你不明白这是什么意思,请保持空白
Optimize for size (Look out for broken compilers!)
编译时优化内核尺寸(使用"-Os"而不是"-O2"参数编译),有时会产生错误的二进制代码
Enable extended accounting over taskstats
收集额外的进程统计信息并通过taskstats接口发送到用户空间
Configure standard kernel features (for small systems)
配置标准的内核特性(为小型系统)
Enable 16-bit UID system calls
允许对UID系统调用进行过时的16-bit包装
Sysctl syscall support
不需要重启就能修改内核的某些参数和变量,如果你也选择了支持/proc,将能从/proc/sys存取可以影响内核行为的参数或变量
Load all symbols for debugging/kksymoops
装载所有的调试符号表信息,仅供调试时选择
Include all symbols in kallsyms
在kallsyms中包含内核知道的所有符号,内核将会增大300K
Do an extra kallsyms pass
除非你在kallsyms中发现了bug并需要报告这个bug才打开该选项
Support for hot-pluggable devices
支持热插拔设备,如usb与pc卡等,Udev也需要它
Enable support for printk
允许内核向终端打印字符信息,在需要诊断内核为什么不能运行时选择
BUG() support
显示故障和失败条件(BUG和WARN),禁用它将可能导致隐含的错误被忽略
Enable ELF core dumps
内存转储支持,可以帮助调试ELF格式的程序
Enable full-sized data structures for core
在内核中使用全尺寸的数据结构.禁用它将使得某些内核的数据结构减小以节约内存,但是将会降低性能
Enable futex support
快速用户空间互斥体可以使线程串行化以避免竞态条件,也提高了响应速度.禁用它将导致内核不能正确的运行基于glibc的程序
Enable eventpoll support
支持事件轮循的系统调用
Use full shmem filesystem
启用shmem支持.shmem是基于共享内存的文件系统(可能用到swap),在启用TMPFS后可以挂载为tmpfs供用户空间使用,它比简单的ramfs先进许多
Use full SLAB allocator
使用SLAB完全取代SLOB进行内存分配,SLAB是一种优秀的内存分配管理器,推荐使用
Enable VM event counters for /proc/vmstat
允许在/proc/vmstat中包含虚拟内存事件记数器
Loadable module support
可加载模块支持
Enable loadable module support
打开可加载模块支持,如果打开它则必须通过"make modules_install"把内核模块安装在/lib/modules/中
Module unloading
允许卸载已经加载的模块
Forced module unloading
允许强制卸载正在使用中的模块(比较危险)
Module versioning support
允许使用其他内核版本的模块(可能会出问题)
Source checksum for all modules
为所有的模块校验源码,如果你不是自己编写内核模块就不需要它
Automatic kernel module loading
让内核通过运行modprobe来自动加载所需要的模块,比如可以自动解决模块的依赖关系
Block layer
块设备层
Enable the block layer
块设备支持,使用硬盘/USB/SCSI设备者必选
Support for Large Block Devices
仅在使用大于2TB的块设备时需要
Support for tracing block io actions
块队列IO跟踪支持,它允许用户查看在一个块设备队列上发生的所有事件,可以通过blktrace程序获得磁盘当前的详细统计数据
Support for Large Single Files
仅在可能使用大于2TB的文件时需要
IO Schedulers
IO调度器
Anticipatory I/O scheduler
适用于大多数环境,但不太合适数据库应用
Deadline I/O scheduler
通常与Anticipatory相当,但更简洁小巧,更适合于数据库应用
CFQ I/O scheduler
为所有进程分配等量的带宽,适合于桌面多任务及多媒体应用
Default I/O scheduler
默认IO调度器
Processor type and features
中央处理器(CPU)类型及特性
Symmetric multi-processing support
对称多处理器支持,如果你有多个CPU或者使用的是多核CPU就选上.此时"Enhanced Real Time Clock Support"选项必须开启,"Advanced Power Management"选项必须关闭
Subarchitecture Type
处理器的子架构,大多数人都应当选择"PC-compatible"
Processor family
处理器系列,请按照你实际使用的CPU选择
Generic x86 support
通用x86支持,如果你的CPU能够在上述"Processor family"中找到就别选
HPET Timer Support
HPET是替代8254芯片的新一代定时器,i686及以上级别的主板都支持,可以安全的选上
Maximum number of CPUs
支持的最大CPU数,每增加一个内核将增加8K体积
SMT (Hyperthreading) scheduler support
支持Intel的超线程(HT)技术
Multi-core scheduler support
针对多核CPU进行调度策略优化
Preemption Model
内核抢占模式
No Forced Preemption (Server)
适合服务器环境的禁止内核抢占
Voluntary Kernel Preemption (Desktop)
适合普通桌面环境的自愿内核抢占
Preemptible Kernel (Low-Latency Desktop)
适合运行实时程序的主动内核抢占
Preempt The Big Kernel Lock
可以抢占大内核锁,应用于实时要求高的场合,不适合服务器环境
Machine Check Exception
让CPU检测到系统故障时通知内核,以便内核采取相应的措施(如过热关机等)
Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4
每5秒检测一次这些cpu的非致命错误并纠正它们,同时记入日志
check for P4 thermal throttling interrupt
当P4的cpu过热时显示一条警告消息
Enable VM86 support
虚拟X86支持,在DOSEMU下运行16-bit程序或XFree86通过BIOS初始化某些显卡的时候才需要
Toshiba Laptop support
Toshiba笔记本模块支持
Dell laptop support
Dell笔记本模块支持
Enable X86 board specific fixups for reboot
修正某些旧x86主板的重起bug,这种主板基本绝种了
/dev/cpu/microcode - Intel IA32 CPU microcode support
使用不随Linux内核发行的IA32微代码,你必需有IA32微代码二进制文件,仅对Intel的CPU有效
/dev/cpu/*/msr - Model-specific register support
在多cpu系统中让特权CPU访问x86的MSR寄存器
/dev/cpu/*/cpuid - CPU information support
能从/dev/cpu/x/cpuid获得CPU的唯一标识符(CPUID)
Firmware Drivers
固件驱动程序
BIOS Enhanced Disk Drive calls determine boot disk
有些BIOS支持从某块特定的硬盘启动(如果BIOS不支持则可能无法启动),目前大多数BIOS还不支持
BIOS update support for DELL systems via sysfs
仅适用于DELL机器
Dell Systems Management Base Driver
仅适用于DELL机器
High Memory Support
最高内存支持,总内存小于等于1G的选"off",大于4G的选"64G"
Memory split
如果你不是绝对清楚自己在做什么,不要改动这个选项
Memory model
一般选"Flat Memory",其他选项涉及内存热插拔
64 bit Memory and IO resources
使用64位的内存和IO资源
Allocate 3rd-level pagetables from highmem
在内存很多(大于4G)的机器上将用户空间的页表放到高位内存区,以节约宝贵的低端内存
Math emulation
数学协处理器仿真,486DX以上的cpu就不要选它了
MTRR (Memory Type Range Register) support
打开它可以提升PCI/AGP总线上的显卡2倍以上的速度,并且可以修正某些BIOS错误
Boot from EFI support
EFI是一种可代替传统BIOS的技术(目前的Grub/LILO尚不能识别它),但是现在远未普及
Enable kernel irq balancing
让内核将irq中断平均分配给多个CPU以进行负载均衡,但是要配合irqbanlance守护进程才行
Use register arguments
使用"-mregparm=3"参数编译内核,将前3个参数以寄存器方式进行参数调用,可以生成更紧凑和高效的代码
Enable seccomp to safely compute untrusted bytecode
只有嵌入式系统可以不选
Timer frequency
内核时钟频率,桌面推荐"1000 HZ",服务器推荐"100 HZ"或"250 HZ"
kexec system call
提供kexec系统调用,可以不必重启而切换到另一个内核
kernel crash dumps
被kexec启动后产生内核崩溃转储
Physical address where the kernel is loaded
内核加载的物理地址,除非你知道自己在做什么,否则不要修改.在提供kexec系统调用的情况下可能要修改它
Support for hot-pluggable CPUs
对热插拔CPU提供支持
Compat VDSO support
如果Glibc版本大于等于2.3.3就不选,否则就选上
更多问题请点这里:
IO调度策略是什么,这几个是什么意思,该选哪个好
你好,具体的请看下面
I/O调度模式:
I/O 即inpu/oupu的缩写,关于数据的读写操作,不同进程请求 数据的优先顺序等等。io调度模式比较复杂,我没有具体测试,这里仅对ray上出现的几个模式做说明,部分参考xda、androidforums、 wik1pedia、linuxarchive资料)
sio
虽然基于deadline,但是它和noop一样,不会对io操作进行排序,所以有着noop那样快速的存取速度,但并没有过多优化io操作。如果不喜欢noop完全不参与调度,也可以选择这个。
noop
这个调度模式会把所有的数据请求直接合并到一个简单的队列里。不适合有机械结构的存储器,因为没有优化顺序,会增加额外的寻道时间。属于最简单的一个调度模式,无视io操作优先级和复杂性,执行完一个再执行一个,如果读写操作繁多的话,就会造成效率降低。
deadline
顾名思义,用过期时间来排序io操作顺序,保证先出现的io请求有最短的延迟时间,相对于写操作,给读操作更优先的级别。是比较好的一个调度模式。
cfq
完全公平队列,是anicipaory模式的替代品,没有过多的做预测性调度,而是根据给定的进程io优先级,直接来分配操作的顺序。这个模式在linux上表现良好,但也许并不是最适合android的io调度模式,太强调均衡,而降低了连续读写数据的性能。
vr
具有和deadline相似的操作排序机制,有着最高的峰值读写速度,但是性能比较不稳定,也就是说可能跑出最高的分数,但是也会出现最低值。
Row
顾名思义ROW=Read over we,最大限制减少IO响应时间,并且重排执行操作,直接进行读写操作,给予IO最高优先值。在移动设备中,它将不会在桌面上有 尽可能多的并行线程。通常它是一个单一的线程或最多2个同时工作的线程读写。有利于阅读的请求通过写入读取的延迟大大降低。比deadline好用,但是 如果线程过多有可能会带来瞬间卡顿)
选择你以适合你的就ok;望采纳!
linux内核怎么调度系统
1.调度器的概述
多任务操作系统分为非抢占式多任务和抢占式多任务。与大多数现代操作系统一样,Linux采用的是抢占式多任务模式。这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器。调度器决定了什么时候停止一个进程以便让其他进程有机会运行,同时挑选出一个其他的进程开始运行。
2.调度策略
在Linux上调度策略决定了调度器是如何选择一个新进程的时间。调度策略与进程的类型有关,内核现有的调度策略如下:
#define SCHED_NORMAL 0#define SCHED_FIFO 1#define SCHED_RR 2#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */#define SCHED_IDLE 5
0: 默认的调度策略,针对的是普通进程。
1:针对实时进程的先进先出调度。适合对时间性要求比较高但每次运行时间比较短的进程。
2:针对的是实时进程的时间片轮转调度。适合每次运行时间比较长得进程。
3:针对批处理进程的调度,适合那些非交互性且对cpu使用密集的进程。
SCHED_ISO:是内核的一个预留字段,目前还没有使用
5:适用于优先级较低的后台进程。
注:每个进程的调度策略保存在进程描述符task_struct中的policy字段
3.调度器中的机制
内核引入调度类(struct sched_class)说明了调度器应该具有哪些功能。内核中每种调度策略都有该调度类的一个实例。(比如:基于公平调度类为:fair_sched_class,基于实时进程的调度类实例为:rt_sched_class),该实例也是针对每种调度策略的具体实现。调度类封装了不同调度策略的具体实现,屏蔽了各种调度策略的细节实现。
调度器核心函数schedule()只需要调用调度类中的接口,完成进程的调度,完全不需要考虑调度策略的具体实现。调度类连接了调度函数和具体的调度策略。
武特师兄关于sche_class和sche_entity的解释,一语中的。
调度类就是代表的各种调度策略,调度实体就是调度单位,这个实体通常是一个进程,但是自从引入了cgroup后,这个调度实体可能就不是一个进程了,而是一个组
4.schedule()函数
linux 支持两种类型的进程调度,实时进程和普通进程。实时进程采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL策略。
preempt_disable():禁止内核抢占
cpu_rq():获取当前cpu对应的就绪队列。
prev = rq-curr;获取当前进程的描述符prev
switch_count = prev-nivcsw;获取当前进程的切换次数。
update_rq_clock() :更新就绪队列上的时钟
clear_tsk_need_resched()清楚当前进程prev的重新调度标志。
deactive_task():将当前进程从就绪队列中删除。
put_prev_task() :将当前进程重新放入就绪队列
pick_next_task():在就绪队列中挑选下一个将被执行的进程。
context_switch():进行prev和next两个进程的切换。具体的切换代码与体系架构有关,在switch_to()中通过一段汇编代码实现。
post_schedule():进行进程切换后的后期处理工作。
5.pick_next_task函数
选择下一个将要被执行的进程无疑是一个很重要的过程,我们来看一下内核中代码的实现
对以下这段代码说明:
1.当rq中的运行队列的个数(nr_running)和cfs中的nr_runing相等的时候,表示现在所有的都是普通进程,这时候就会调用cfs算法中的pick_next_task(其实是pick_next_task_fair函数),当不相等的时候,则调用sched_class_highest(这是一个宏,指向的是实时进程),这下面的这个for(;;)循环中,首先是会在实时进程中选取要调度的程序(p = class-pick_next_task(rq);)。如果没有选取到,会执行class=class-next;在class这个链表中有三种类型(fair,idle,rt).也就是说会调用到下一个调度类。
static inline struct task_struct *pick_next_task(struct rq *rq){ const struct sched_class *class; struct task_struct *p; /*
* Optimization: we know that if all tasks are in
* the fair class we can call that function directly:
*///基于公平调度的普通进程
if (likely(rq-nr_running == rq-cfs.nr_running)) {
p = fair_sched_class.pick_next_task(rq); if (likely(p)) return p;
}//基于实时调度的实时进程
class = sched_class_highest; for ( ; ; ) {
p = class-pick_next_task(rq); //实时进程的类
if (p) return p; /*
* Will never be NULL as the idle class always
* returns a non-NULL p:
*/
class = class-next; //rt-next = fair; fair-next = idle
}
}
在这段代码中体现了Linux所支持的两种类型的进程,实时进程和普通进程。回顾下:实时进程可以采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL调度策略。
在这里首先说明一个结构体struct rq,这个结构体是调度器管理可运行状态进程的最主要的数据结构。每个cpu上都有一个可运行的就绪队列。刚才在pick_next_task函数中看到了在选择下一个将要被执行的进程时实际上用的是struct rq上的普通进程的调度或者实时进程的调度,那么具体是如何调度的呢?在实时调度中,为了实现O(1)的调度算法,内核为每个优先级维护一个运行队列和一个DECLARE_BITMAP,内核根据DECLARE_BITMAP的bit数值找出非空的最高级优先队列的编号,从而可以从非空的最高级优先队列中取出进程进行运行。
我们来看下内核的实现
struct rt_prio_array {
DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */
struct list_head queue[MAX_RT_PRIO];
};
数组queue[i]里面存放的是优先级为i的进程队列的链表头。在结构体rt_prio_array 中有一个重要的数据构DECLARE_BITMAP,它在内核中的第一如下:
define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
5.1对于实时进程的O(1)算法
这个数据是用来作为进程队列queue[MAX_PRIO]的索引位图。bitmap中的每一位与queue[i]对应,当queue[i]的进程队列不为空时,Bitmap的相应位就为1,否则为0,这样就只需要通过汇编指令从进程优先级由高到低的方向找到第一个为1的位置,则这个位置就是就绪队列中最高的优先级(函数sched_find_first_bit()就是用来实现该目的的)。那么queue[index]-next就是要找的候选进程。
如果还是不懂,那就来看两个图
注:在每个队列上的任务一般基于先进先出的原则进行调度(并且为每个进程分配时间片)
在内核中的实现为:
static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, struct rt_rq *rt_rq){ struct rt_prio_array *array = rt_rq-active; struct sched_rt_entity *next = NULL; struct list_head *queue; int idx;
idx = sched_find_first_bit(array-bitmap); //找到优先级最高的位
BUG_ON(idx = MAX_RT_PRIO); queue = array-queue + idx; //然后找到对应的queue的起始地址
next = list_entry(queue-next, struct sched_rt_entity, run_list); //按先进先出拿任务
return next;
}
那么当同一优先级的任务比较多的时候,内核会根据
位图:
将对应的位置为1,每次取出最大的被置为1的位,表示优先级最高:
5.2 关于普通进程的CFS算法:
我们知道,普通进程在选取下一个需要被调度的进程时,是调用的pick_next_task_fair函数。在这个函数中是以调度实体为单位进行调度的。其最主要的函数是:pick_next_entity,在这个函数中会调用wakeup_preempt_entity函数,这个函数的主要作用是根据进程的虚拟时间以及权重的结算进程的粒度,以判断其是否需要抢占。看一下内核是怎么实现的:
wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
{
s64 gran, vdiff = curr-vruntime - se-vruntime;//计算两个虚拟时间差//如果se的虚拟时间比curr还大,说明本该curr执行,无需抢占
if (vdiff = 0) return -1;
gran = wakeup_gran(curr, se); if (vdiff gran) return 1; return 0;
}
gran为需要抢占的时间差,只有两个时间差大于需要抢占的时间差,才需要抢占,这里避免太频繁的抢占
wakeup_gran(struct sched_entity *curr, struct sched_entity *se)
{
unsigned long gran = sysctl_sched_wakeup_granularity; if (cfs_rq_of(curr)-curr sched_feat(ADAPTIVE_GRAN))
gran = adaptive_gran(curr, se);
/*
* Since its curr running now, convert the gran from real-time
* to virtual-time in his units.
*/ if (sched_feat(ASYM_GRAN)) {
/*
* By using 'se' instead of 'curr' we penalize light tasks, so
* they get preempted easier. That is, if 'se' 'curr' then
* the resulting gran will be larger, therefore penalizing the
* lighter, if otoh 'se' 'curr' then the resulting gran will
* be smaller, again penalizing the lighter task.
*
* This is especially important for buddies when the leftmost
* task is higher priority than the buddy.
*/ if (unlikely(se-load.weight != NICE_0_LOAD))
gran = calc_delta_fair(gran, se);
} else { if (unlikely(curr-load.weight != NICE_0_LOAD))
gran = calc_delta_fair(gran, curr);
} return gran;
}
6.调度中的nice值
首先需要明确的是:nice的值不是进程的优先级,他们不是一个概念,但是进程的Nice值会影响到进程的优先级的变化。
通过命令ps -el可以看到进程的nice值为NI列。PRI表示的是进程的优先级,其实进程的优先级只是一个整数,它是调度器选择进程运行的基础。
普通进程有:静态优先级和动态优先级。
静态优先级:之所有称为静态优先级是因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级用进程描述符中的static_prio来表示。在内核中/kernel/sched.c中,nice和静态优先级的关系为:
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
动态优先级:调度程序通过增加或者减小进程静态优先级的值来奖励IO小的进程或者惩罚cpu消耗型的进程。调整后的优先级称为动态优先级。在进程描述中用prio来表示,通常所说的优先级指的是动态优先级。
由上面分析可知,我们可以通过系统调用nice函数来改变进程的优先级。
#include stdlib.h#include stdio.h#include math.h#include unistd.h#include sys/time.h#define JMAX (400*100000)#define GET_ELAPSED_TIME(tv1,tv2) ( \
(double)( (tv2.tv_sec - tv1.tv_sec) \
+ .000001 * (tv2.tv_usec - tv1.tv_usec)))//做一个延迟的计算double do_something (void){ int j; double x = 0.0; struct timeval tv1, tv2;
gettimeofday (tv1, NULL);//获取时区
for (j = 0; j JMAX; j++)
x += 1.0 / (exp ((1 + x * x) / (2 + x * x)));
gettimeofday (tv2, NULL); return GET_ELAPSED_TIME (tv1, tv2);//求差值}int main (int argc, char *argv[]){ int niceval = 0, nsched; /* for kernels less than 2.6.21, this is HZ
for tickless kernels this must be the MHZ rate
e.g, for 2.6 GZ scale = 2600000000 */
long scale = 1000; long ticks_cpu, ticks_sleep; pid_t pid;
FILE *fp; char fname[256]; double elapsed_time, timeslice, t_cpu, t_sleep; if (argc 1)
niceval = atoi (argv[1]);
pid = getpid (); if (argc 2)
scale = atoi (argv[2]); /* give a chance for other tasks to queue up */
sleep (3); sprintf (fname, "/proc/%d/schedstat", pid);//读取进程的调度状态
/*
在schedstat中的数字是什么意思呢?:
*/
/* printf ("Fname = %s\n", fname); */
if (!(fp = fopen (fname, "r"))) { printf ("Failed to open stat file\n"); exit (-1);
} //nice系统调用
if (nice (niceval) == -1 niceval != -1) { printf ("Failed to set nice to %d\n", niceval); exit (-1);
}
elapsed_time = do_something ();//for 循环执行了多长时间
fscanf (fp, "%ld %ld %d", ticks_cpu, ticks_sleep, nsched);//nsched表示调度的次数
t_cpu = (float)ticks_cpu / scale;//震动的次数除以1000,就是时间
t_sleep = (float)ticks_sleep / scale;
timeslice = t_cpu / (double)nsched;//除以调度的次数,就是每次调度的时间(时间片)
printf ("\nnice=%3d time=%8g secs pid=%5d"
" t_cpu=%8g t_sleep=%8g nsched=%5d"
" avg timeslice = %8g\n",
niceval, elapsed_time, pid, t_cpu, t_sleep, nsched, timeslice);
fclose (fp); exit (0);
}
说明: 首先说明的是/proc/[pid]/schedstat:在这个文件下放着3个变量,他们分别代表什么意思呢?
第一个:该进程拥有的cpu的时间
第二个:在对列上的等待时间,即睡眠时间
第三个:被调度的次数
由结果可以看出当nice的值越小的时候,其睡眠时间越短,则表示其优先级升高了。
7.关于获取和设置优先级的系统调用:sched_getscheduler()和sched_setscheduler
#include sched.h#include stdlib.h#include stdio.h#include errno.h#define DEATH(mess) { perror(mess); exit(errno); }void printpolicy (int policy){ /* SCHED_NORMAL = SCHED_OTHER in user-space */
if (policy == SCHED_OTHER) printf ("policy = SCHED_OTHER = %d\n", policy); if (policy == SCHED_FIFO) printf ("policy = SCHED_FIFO = %d\n", policy); if (policy == SCHED_RR) printf ("policy = SCHED_RR = %d\n", policy);
}int main (int argc, char **argv){ int policy; struct sched_param p; /* obtain current scheduling policy for this process */
//获取进程调度的策略
policy = sched_getscheduler (0);
printpolicy (policy); /* reset scheduling policy */
printf ("\nTrying sched_setscheduler...\n");
policy = SCHED_FIFO;
printpolicy (policy);
p.sched_priority = 50; //设置优先级为50
if (sched_setscheduler (0, policy, p))
DEATH ("sched_setscheduler:"); printf ("p.sched_priority = %d\n", p.sched_priority); exit (0);
}
输出结果:
[root@wang schedule]# ./get_schedule_policy policy = SCHED_OTHER = 0
Trying sched_setscheduler...
policy = SCHED_FIFO = 1
p.sched_priority = 50
可以看出进程的优先级已经被改变。
手机的CPU调节器和I/O调度器分别是什么意思?
powersave省电模式但反应慢 interactive这个是自由升降模式,可以用。
performance高性能模式但费电,如果选择那个ondemand又省电又有性能。I/O选择cfq,正常模式。setcpu开机后,调整CPU频率,该频率可以超频CPU主频的提高,或降低,可节省。
Android的CPU的频率并不是一成不变的,会因应程式所需而调整频率,通常会视乎CPU Loading% 而升/降频,在特定时间再检查是否升/降。I/O即input/output的缩写关于数据的读写操作不同进程请求数据的优先顺序等等。
扩展资料:
CPU的频率并不是一成不变的,会根据机器的需要而调整频率,这就需要有一个规则去规范,要不就乱套了,设置这个规则就是CPU调速器。CPU调速器的设置影响两个指数:使用舒适度和耗电,也就是响应速度、流畅度、稳定性和费不费电。
手机CPU调节器CPU-Z是一款非常厉害的CPU管理工具,这款软件在PC平台上早就非常受欢迎了,后来作者制作了安卓版的CPU-Z,在Android手机上就可以体验了,和pc的功能一样,CPU-Z 也是可以查看的参数非常丰富,CPU 核心、GPU、电池、传感器、发热等相关信息。
如何查看linux的io调度器
命令为 iostat 如果提示命令找不到,请先安装 安装命令为 yum install sysstat