1. 进程调度

the process scheduler is the component of a kernel that selects which process to run next.
进程调度器需要使 处理器使用率最大化,并且提供 使多个进程并发执行的虚拟
 
Deciding which processes run, when, and for how long is the process scheduler's fundamental responsibility.
 
时间片:the scheduler allocates the process a “slice” of the processor's time
 
Linux进程调度算法CFS( Completely Fair Scheduler):enforce fair access to a resource among contending consumers
 

2. 时间片

如果时间片过大,那么 挂起进程 开始执行前的等待时间过长,这将减小 并发执行的粒度,甚至用户觉察到延迟
如果时间片过小,那么 系统在进程之间切换的时间花销将很大,时间局部性的优势将丧失
 
CPU密集型:processes are hungry for CPU time,比如科学计算、数学计算、图像处理
I/O密集型:spend more time blocked waiting for some resource than executing,often issuing and waiting for file or network I/O, blocking on keyboard input
 

3. CFS调度

传统Unix进程调度中,有两个最基础的变量:优先级和时间片
CFS引进 fair scheduling 算法,CFS赋予每个进程一定比例的处理器时间,而不是时间片
开始时,CFS赋予N个进程等同的 1/N 处理器时间,然后权衡每个进程比例进行动态调整
Processes with the default nice value of zero have a weight of one, so their proportion is unchanged
Processes with a smaller nice value (higher priority) receive a larger weight, increasing their fraction of the processor
process with a larger nice value (lower priority) receive a smaller weight, decreasing their fraction of the processor
 
为了确定每个进程每次运行的实际时间,CFS needs to divide the proportions into a fixed period
例如:20毫秒,2个相同优先级的进程,则每个进程赋予相同的权重和处理器时间比例,即每个进程10毫秒
如果是5个进程,则每个进程分配4毫秒,如果是200个进程呢?
按照常理应该是 每个进程分配100微秒,但是由于 上下文切换开销巨大,并且 局部性优势丧失,这将严重影响系统的吞吐率
 
这时CFS引入另一个变量:minimum granularity (最小粒度)
minimum granularity是任一进程运行时间长度的下限,这将保证 上下文切换开销占 系统总时间开销的比例 不会过大
 
By assigning proportions of the processor and not fixed timeslices,CFS is able to enforce fairness: each process gets its fair share of the processor
 

4. nice val

processes are assigned priorities that affect how long they run,Unix has historically called these priorities nice values
Legal nice values range from −20 to 19 inclusive, with a default value of 0, nice值越大,优先级越低,nice值越小,优先级越高
 
/* increments a process's nice value by inc and returns the newly updated value */
#include <unistd.h> int nice (int inc);
Passing 0 for inc is an easy way to obtain the current nice value 
nice函数错误时返回-1,但是 新的nice值也可能就是-1,为了区分 函数错误 和 返回nice新值为-1,则如下使用:
int ret;
errno = ;
ret = nice (); /* increase our nice by 10 */
if (ret == − && errno != )
perror ("nice");
else
printf ("nice value is now %d\n", ret);

获取/设置优先级:

#include <sys/time.h>
#include <sys/resource.h>
int getpriority (int which, int who);
int setpriority (int which, int who, int prio);
/* returns the current process’s priority */
int ret;
ret = getpriority (PRIO_PROCESS, );
printf ("nice value is %d\n", ret);
/* sets the priority of all processes in the current process group to 10 */
int ret;
ret = setpriority (PRIO_PGRP, , );
if (ret == −)
perror ("setpriority");

5. 处理器关联

the process scheduler must decide which processes run on each CPU
如果一个进程在一个CPU核上被调度,the process scheduler should aim to schedule it on the same CPU in the future
因为 进程从一个CPU核迁移到另一个CPU核的代价是巨大的(主要是缓存影响)
 
if a process moves to a new CPU and writes new data into memory, the data in the old  CPU's cache can become stale
这样,进程调度器必须在 进程迁移CPU花销 和 多个CPU负载均衡 之间取得平衡
 
The Linux scheduler attempts to schedule the same processes on the same processors for as long as possible, migrating a process from one CPU
to another only in situations of extreme load imbalance. This allows the scheduler to minimize the  cache effects of migration but still ensure that
all processors in a system are evenly  loaded
 

6. 实时系统

硬实时和软实时
A hard real-time system requires absolute adherence to operational deadlines
A soft real-time system does not consider over‐running a deadline to be a critical failure
 

7. Linux实时调度策略

FIFO调度:A FIFO-classed process will continue running so long as no higher-priority process becomes runnable
时间片轮转:When an RR-classed process exhausts its timeslice, the scheduler moves it to the end of the list of processes at  its priority
注意:这两种实时调度策略中,如果存在更高优先级的进程,那么低优先级进程将不会运行
int policy;
/* get our scheduling policy */
policy = sched_getscheduler ();
switch (policy) {
case SCHED_OTHER:
printf ("Policy is normal\n");
break;
case SCHED_RR:
printf ("Policy is round-robin\n");
break;
case SCHED_FIFO:
printf ("Policy is first-in, first-out\n");
break;
case -:
perror ("sched_getscheduler");
break;
default:
fprintf (stderr, "Unknown policy!\n");
}
Linux implements a range of 1 to 99 inclusive for the two real-time scheduling policies
Linux provides two system calls for retrieving the range of valid priority values:
int min, max;
min = sched_get_priority_min (SCHED_RR);
if (min == −) {
perror ("sched_get_priority_min");
return ;
}
max = sched_get_priority_max (SCHED_RR);
if (max == −) {
perror ("sched_get_priority_max");
return ;
}
printf ("SCHED_RR priority range is %d - %d\n", min, max);
实时调度的注意事项:
设计实时程序必须格外小心,can easily bring down the entire system
(1) 如果系统中没有更高优先级的实时进程,CPU密集型 循环程序将会 一直运行到结束
(2) Take care not to starve the rest of the system of processor time
(3) If a real-time process busy-waits for a resource held by a lower-priority process, the real-time process will busy-wait forever.
(因为低优先级进程不会运行从而释放资源)

Linux System Programming 学习笔记(六) 进程调度的更多相关文章

  1. Linux System Programming 学习笔记(十一) 时间

    1. 内核提供三种不同的方式来记录时间 Wall time (or real time):actual time and date in the real world Process time:the ...

  2. Linux System Programming 学习笔记(七) 线程

    1. Threading is the creation and management of multiple units of execution within a single process 二 ...

  3. Linux System Programming 学习笔记(四) 高级I/O

    1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and mu ...

  4. Linux System Programming 学习笔记(二) 文件I/O

    1.每个Linux进程都有一个最大打开文件数,默认情况下,最大值是1024 文件描述符不仅可以引用普通文件,也可以引用套接字socket,目录,管道(everything is a file) 默认情 ...

  5. Linux System Programming 学习笔记(一) 介绍

    1. Linux系统编程的三大基石:系统调用.C语言库.C编译器 系统调用:内核向用户级程序提供服务的唯一接口.在i386中,用户级程序执行软件中断指令 INT n 之后切换至内核空间 用户程序通过寄 ...

  6. Linux System Programming 学习笔记(十) 信号

    1. 信号是软中断,提供处理异步事件的机制 异步事件可以是来源于系统外部(例如用户输入Ctrl-C)也可以来源于系统内(例如除0)   内核使用以下三种方法之一来处理信号: (1) 忽略该信号.SIG ...

  7. Linux System Programming 学习笔记(九) 内存管理

    1. 进程地址空间 Linux中,进程并不是直接操作物理内存地址,而是每个进程关联一个虚拟地址空间 内存页是memory management unit (MMU) 可以管理的最小地址单元 机器的体系 ...

  8. Linux System Programming 学习笔记(八) 文件和目录管理

    1. 文件和元数据 每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number 一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是L ...

  9. Linux System Programming 学习笔记(五) 进程管理

    1. 进程是unix系统中两个最重要的基础抽象之一(另一个是文件) A process is a running program A thread is the unit of activity in ...

随机推荐

  1. Feign-手动创建FeignClient

    前言 在<Feign-请求不同注册中心的服务>中,提到,如果需要请求不同注册中心的服务,可以设置@FeignClient的url属性. 这种做法有个缺点,需要服务消费者,配置各个环境的ur ...

  2. Python——序列封包与序列解包

    一.序列封包与序列解包 把多个值赋给一个变量时,Python会自动的把多个值封装成元组,称为序列封包. 把一个序列(列表.元组.字符串等)直接赋给多个变量,此时会把序列中的各个元素依次赋值给每个变量, ...

  3. vscode的eslint插件不起作用

    最近在用vue进行开发,但是vsCode中的eslint插件装上之后不起作用 1.vsCode打开“设置”,选择"settings.json" 2.输入一段脚本 "esl ...

  4. git 指令记录

    由于之前一直用svn 用git也是用图形化的工具 还是要了解一下git指令 因为都是版本控制工具 有很多相似之处 所以理解起来也比较轻松 仓库: github上面的项目 工作目录下面的所有文件都不外乎 ...

  5. ipvsadm分发MySQL读请求

    在MySQL的部署场景中,经常使用HAproxy和ipvs来作为读请求转发的网关.ipvs的好处在于本身不需要daemon的方式来运行,而是直接作为kernel的服务来提供:当ipvs和应用程序服务器 ...

  6. 关于PHP连接池扩展php-cp遇到的那些坑

    php-cp是国内大神写的php第三方扩展,具体就不用多说了,细读https://github.com/swoole/php-cp,下面来说说今天安装方法. 环境:CentOS7.2.1511 由于本 ...

  7. PHP 代码优化建议

    1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4,甚至我测试的时候,这个提高了近三倍.当然了,这个测试方法需要在十万级以上次执行,效果才明显.其实静态方法和非静态方法的效率 ...

  8. 【php】【趣味代码】对象引用的比较

    <?php $a = new stdClass(); $a->name = 'flint'; $b = $a ; $b->sex = 'man'; saveObject($b); f ...

  9. Thinkphp5 的常用连式查询

    目录 取出表中改字符串前两位等于01的数据 按主键查询 不按主键查 JOIN方法 的左右连接 not in 方法 like 查询 where 按条件筛选查询 取出表中改字符串前两位等于01的数据 $p ...

  10. loj2182 「SDOI2015」寻宝游戏

    参考这里 #include <iostream> #include <cstdio> #include <set> using namespace std; typ ...