第一次作业:关于Linux 2.6.20进程模型和O(1)调度器算法的分析

1.写在最前

本文基于 Linux Kernel 2.6.20 的源代码,分析的是本版本linux的进程模型和其O(1) 调度器的基本算法。
源码浏览地址:
https://elixir.bootlin.com/linux/v2.6.20/source

2.关于进程

2.1进程的定义

从不同的角度,进程可以有不同的定义,比较经典的定义有:

1) 进程是程序的一次执行过程

2) 进程是一个程序及其数据在处理器上顺序执行时所发生的活动。

3) 进程是具有独立功能的程序在一个数据集合上运行的过程,他是系统进行资源分配和调度的一个独立单位。

在引入了进程实体的概念后,我们可以把传统的操作系统中的进程定义为:

“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”。

2.2看一眼进程

我们可以使用$ps查询正在运行的进程,
比如$ps -eo pid,comm,cmd,
下图为执行结果(部分):
enter image description here
(-e表示列出全部进程,-o pid,comm,cmd表示我们需要PID,COMMAND,CMD信息)

3.关于进程的组织

linux将进程的列表存放在叫做任务队列的双向循环链表中。
链表中的每一项都是类型为task_struct,称为进程描述符,该结构定义在<linux/sched.h>文件中。
进程描述符中包含一个具体进程的所有信息。
其包含的数据能完整地描述一个正在执行的程序:进程标识符(PID),进程状态,优先级等其他所有信息。

3.1进程标识符

pid_t pid;

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/include/linux/sched.h#L855

PID(process IDentity)是一个整数,每一个进程都有一个唯一的PID来代表自己的身份,进程也可以根据PID来识别其他的进程。
在CONFIG_BASE_SMALL配置为0的情况下,PID的取值范围是0到32767,即系统中的进程数最大为32768个,已可满足普通用户的日常使用。

#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/include/linux/threads.h#L27

3.2进程状态

volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/include/linux/sched.h#L802

state的可能取值有

#define TASK_RUNNING        0
#define TASK_INTERRUPTIBLE  1
#define TASK_UNINTERRUPTIBLE    2
#define TASK_STOPPED        4
#define TASK_TRACED     8
/* in tsk->exit_state */
#define EXIT_ZOMBIE     16
#define EXIT_DEAD       32
/* in tsk->state again */
#define TASK_NONINTERACTIVE 64
#define TASK_DEAD       128

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/include/linux/sched.h#L143

接下来对几个常用状态进行简单的分析。

状态描述
TASK_RUNNING进程正在执行 或者 进程正在准备执行。
TASK_INTERRUPTIBLE进程由于等待某些条件处于阻塞(挂起的状态),一旦等待的条件成立,便会从该状态变成TASK_RUNNING。这些条件主要包括:硬中断、资源、某些信号等等。
TASK_UNINTERRUPTIBLE与TASK_INTERRUPTIBLE类似。但我们传递任何信号都无法唤醒它,只有当它所等待的资源可用时,它才被唤醒。
TASK_STOPPED进程停止执行。当进程接收到SIGSTOP、SIGTTIN、SIGTSTP或者SIGTTOU信号等之后就会进入该状态。
TASK_TRACED进程被debugger等进程监视。进程执行被调试程序所停止,当一个进程被另外的进程所监视,每一个信号都会让进城进入该状态。
EXIT_ZOMBIE进程的执行被终止,但其父进程还未使用wait()等系统调用来获取它的终止信息,此时进程成为僵尸进程。
EXIT_DEAD进程被“杀死”,也就是进程的最终状态。

而进程状态之间的转换,大致如下图。
enter image description here

3.3优先级

int prio, static_prio, normal_prio;

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/include/linux/sched.h#L815

简单分析
字段 | 描述
--- | ---
prio|保存动态优先级
static_prio|保存静态优先级
normal_prio|它的值取决于优先策略和静态优先级

4.关于O(1)调度算法

4.1 调度器与进程

调度器:
通常来说,操作系统是应用程序和可用资源之间的媒介。

典型的资源有内存和物理设备。

CPU也可以认为是一个资源,调度器可以临时分配一个任务在上面执行(单位是时间片)。调度器使得我们同时执行多个程序成为可能,因此可以与具有各种需求的用户共享CPU。所以,如何高效地分配CPU时间片,是调度器 的重要目标。

活动进程和过期进程:
调度器为每一个CPU维护了两个进程队列数组:active数组和expire数组。

active进程: 那些还没有用完时间片的进程
expire进程: 那些已经用完时间片的进程

调度程序的工作就是在活动进程集合中选取一个最佳优先级的进程,如果该进程时间片恰好用完,就将该进程放入过期进程集合中.

4.2 满足O(1)的数据结构?

通过在数据结构课上的知识,大多数算法的时间复杂度在O(log N) 基本上就是最好的结果,那么2.6 的 O(1) 调度算法是怎么做到的?

在回答这个问题之前,我们先回顾一下数据结构的四种基本操作以及其时间复杂度:

  • access:随机访问。array 是唯一满足 O(1) 随机访问的数据结构。
  • search:搜索。hash table 是 O(1) 时间复杂度的,但最坏情况下是 O(N) 的。大部分 tree(b-tree / red-black tree)平均情况和最坏情况都是 O(log N)。
  • insert/deletion:插入和删除。linked list,stack,queue 在平均和最坏情况下都是 O(1)。

综上,若想达成 O(1) scheduler 的目标,操作只能包含纯粹的 access,insert 和 deletion,不能有 search。

此外,对于 scheduler,我们应该尽量要选择平均情况和最坏情况表现一致的算法。如果平均情况是 O(1),最坏情况是 O(n),那么这个 scheduler 会给系统带来很大的不确定性

所以我们的选择并不多。
对于access 只能用 array,
对于insert / deletion 只能用 linked list / queue / stack。

4.3 算法思路

我们先看一张大神给出的正确答案。
enter image description here

在linux中一共有140 种不同的优先级,所以我们就用长度为 140 的 array 去记录优先级。在每个优先级下使用 FIFO queue 来管理该优先级下的所有 process。新来的插到队尾,先进先出。此时,insert / deletion 都是 O(1)。
但,应该如何找到当前最高优先级下的process?若从优先级 0 开始遍历,算法显然不是O(1)。在 2.6 scheduler 里采用 bitarray,为每种优先级分配一个 bit,若该优先级队列下有 process,那么对相应的 bit 染色,置为 1,否则置为 0。

现在,问题简化成寻找一个 bitarray 中最高位是 1 的 bit(left-most bit)。

4.4 重要数据结构

struct runqueue(运行队列):每个cpu都有一个运行队列

struct rq {
    spinlock_t lock;
    unsigned long nr_running;
    unsigned long raw_weighted_load;
    unsigned long cpu_load[3];
    unsigned long long nr_switches;
    unsigned long nr_uninterruptible;
    unsigned long expired_timestamp;
    /* Cached timestamp set by update_cpu_clock() */
    unsigned long long most_recent_timestamp;
    struct task_struct *curr, *idle;
    unsigned long next_balance;
    struct mm_struct *prev_mm;
    struct prio_array *active, *expired, arrays[2];
    int best_expired_prio;
    atomic_t nr_iowait;
    ...
    }

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/kernel/sched.c#L205
其中最最重要的部分便是prio_array。
prio_array(优先级数组)
O(1)算法的核心数据结构即为prio_array结构体。

struct prio_array {
    unsigned int nr_active;
    DECLARE_BITMAP(bitmap, MAX_PRIO+1); /* include 1 bit for delimiter */
    struct list_head queue[MAX_PRIO];
};

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/kernel/sched.c#L192

其中

  • bitmap:优先级位图,它使用一个位(bit)来代表一个优先级。
  • queue:表示进程动态优先级的数组,它包含了每一种优先级进程所形成的链表。

4.5 O(1)调度算法的实现

schedule()是实现进程调度的主要函数,并且负责完成进程切换工作,其用于确定最高优先级进程的代码非常快捷高效。它在kernel/sched.c中的定义如下

asmlinkage void __sched schedule(void)
{
    struct task_struct *prev, *next;
    struct prio_array *array;
    struct list_head *queue;
    unsigned long long now;
    unsigned long run_time;
    int cpu, idx, new_prio;
    long *switch_count;
    struct rq *rq;
    ...
}

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/kernel/sched.c#L3412
其中,选择候选进程的关键代码为:

    idx = sched_find_first_bit(array->bitmap);
    queue = array->queue + idx;
    next = list_entry(queue->next, struct task_struct, run_list);

*来源:https://elixir.bootlin.com/linux/v2.6.20/source/kernel/sched.c#L3509

例如:在queue[i]中,存放的计时优先级为i的进程队列的链表头。而bitmap是用来作为进程队列queue的索引位图。
bitmap的每一位都与queue[i]对应。当queue[i]的进程队列不为空时,bitmap的对应位就为1,否则为0。
现在只需要使用汇编指令按照进程优先级从高到底的方向找到第一个为1的位置idx,idx就是当前运行队列中最高的优先级数(函数sched_find_first_bit()便是用来完成这一功能)。
那么,queue[idx]->next便是我们要找的候选进程。
当active数组中的所有进程都被移到expire数组中后,调度器交换active数组和expire数组。
当进程被移入expire数组时,调度器会重置其时间片,因此新的active数组又恢复了初始情况,而expire数组为空,从而开始新的一轮调度。

4.6 更多细节

除了选取最高优先级进程外,O(1)算法还有其他许多的细节,比如进程动态优先级的计算,调度与抢占时机,由于个人水平原因,无法一一阐述。

5.感受与总结

通过查阅资料我得知在linux2.4版本时,2.4的O(n)scheduler早已被诟病已久。
而在划时代的2.6版本中 O(1)scheduler的出现想必一定让当时的开发者兴奋不已。虽然如今的linux所使用的是更加强调公平性的 CFS(Completely Fair Scheduler),但它依旧用简单的算法和独特的设计取得了自己的地位并且影响更多的开发者。无论任何调度器算法都还无法满足所有应用的需要,CFS也有一些负面的测试报告。相信随着Linux的不断发展,更多开发者的不懈努力,还会出现更好的调度算法。

6.参考资料

  1. https://wenku.baidu.com/view/c14310d4b9f3f90f76c61b41.html
  2. https://blog.youkuaiyun.com/fangjian1204/article/details/39736725
  3. http://edsionte.com/techblog/archives/2851
  4. http://abcdxyzk.github.io/blog/2015/01/22/kernel-sched-n1/
  5. https://www.ibm.com/developerworks/cn/linux/l-cn-scheduler/

转载于:https://www.cnblogs.com/xgbt/p/8869313.html

【Linux】深入理解进程的优先级(Linux 2.6版本O(1)调度算法) 然后CPU运行活动队列,不需要管新加入的进程,统一将新加入的进程放到过期队列中,过期队列其实就相当于是活动队列的一个镜像,新加入的进程就根据优先级映射到对应的数组下标,然后添加进对应位置的哈希桶里面,当CPU把运行队列里的内容都执行完了。而一个CPU通常一次只能调度一个进程,而操作系统里是有很多的进程需要被调度的,所以这就意味着,这些等待被调度的进程就要进行排队,而排队就要有先后的顺序,也就是进程的优先级,但是这样线性遍历的时间复杂度是一个O(N)级别的,我们操作系统响应是非常快的,这显然不合适。 阅读详情

相关推荐

Linux调度算法演进与分析

一、前言 1.1 叙叙旧 这篇博客是自己在学习高级操作系统时,老师让我们选择一个感兴趣的题目,写一篇技术报告。自己和小组的同学商量了一下,决定选择Linux调度算法的演进。由于整个技术报告有30页,这里选择其中的核心部分进行表述(同时为了保证小组同学的权益,这部分也是自己写的一部分),希望能够让大家了解Linux调度算法有一定的帮助。 1.2 文章摘要 调度算法是操作系统高效公平运行的核心,如何实...

wd 3275

O(1)调度器:Linux2.6版本的核心算法

全局优先级,范围为0~139,数值越低,优先级越高将进程拆分成实时进程(0 ~ 99)和普通进程(100 ~ 139),更高优先级任务获得更多的时间片支持抢占,当任务状态变成TASK_RUNNING时,内核会检查其优先级是否比当前任务的优先级更高,如果是的话,则抢占当前正在运行的任务,切换到该任务实时进程使用静态优先级普通进程使用动态优先级,任务优先级会在其使用完自己的时间片后重新计算,内核会考虑它过去的行为,决定它的交互等级,交互型任务更容易得到调度。

嵌入式Linux内核的博客 795

【Linux 内核源码分析】进程调度 -CFS 调度器

在CFS(Completely Fair Scheduler)调度器中,任务的权重值由其nice值决定,通过对比不同任务的权重值,CFS会分配合理的CPU时间片给每个任务。这种方式实现了一种类似于多态的效果,即不同的任务可以使用不同的调度算法,而调度器的函数指针则根据具体的调度器类型来指向对应的函数。通过这种方式,Linux 内核可以根据任务的调度器类型来调用相应的调度函数,实现了灵活的调度策略,并且能够方便地扩展和切换不同的调度器。高优先级的任务会获得更多的虚拟运行时间,在排序和选择调度时更容易被选中。

C/C++Linux、音视频、DPDK 1531

Linux源码剖析——O(1)调度算法

当一个普通进程被添加到运行队列时,会先计算其动态优先级,然后按照动态优先级的值来添加到对应优先级的队列中。Linux2.4版本使用的调度算法的时间复杂度为O(n),其主要原理是通过轮询所有可运行任务列表,然后挑选一个最合适的任务运行,所以其时间复杂度与可运行任务队列的长度成正比。每个进程都要一个动态优先级和静态优先级,静态优先级不会变化(进程创建时被设置),而动态优先级会随着进程的睡眠时间而发生变化。--p->time_slice) { // 减少时间片, 如果时间片用完。

白话机器学习 724

linux 2.6.20.1源码

linux 2.6.20.1源码

Linux Kernel 2.6进程调度分析

Linux Kernel 2.6进程调度分析 -- Linux Kernel 2.6进程调度分析

深入解读Linux进程调度Schedule【转】

转自:https://blog.csdn.net/Vince_/article/details/88982802 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/Vince_/article/details/88982802长文慎入~~ 调度系统是现代操作系统非常核心的基础子...

weixin_30919571的博客 438

TMS320F28377D/F28379D CAN通信避坑指南:从寄存器配置到中断处理的完整流程

本文详细解析了TMS320F28377D/F28379D在CAN通信开发中的关键技术与避坑指南,涵盖时钟配置、寄存器初始化、中断处理等完整流程。针对工业控制和汽车电子应用,提供了实用的优化技巧和错误诊断方法,帮助开发者高效实现稳定可靠的CAN通信。

weixin_30954265的博客 492

进程管理(十五)---进程调度演变过程之O(n)调度器

1 调度器概述 任务调度器是操作系统中一个很重要的功能部件,主要功能是把系统中的task调度到各个CPU上去执行,满足如下的性能需求: 调度器必须是公平的:(对于分时的进程,每个任务都应该有机会执行,不能饿死,保证每个进程得到合理的CPU时间) 快速的进程响应时间:(对于交互式进程,需要和用户进行交流,因此对调度延迟比较敏感) 高系统的吞吐量:(对于批处理进程进程,属于那种在后台的默默奉献的,因此它更注重吞吐量的需求) 功耗要小:(对于移动式终端,功耗的需求其实一直以来都没有特别被调度器重视,当然在lin

奇小葩 1255

MarkDown简介(深度解析MarkDown用法)

欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I...

酷酷的旭 7343

5.1 rocr-runtime libhsakmt event 机制全景—从 Doorbell 到 Signal

本文介绍了ROCm/KFD中的Event机制架构,主要解决GPU异步计算中的反馈问题。Event机制分为三层:硬件层触发事件,内核层管理事件通知,用户态接收处理。事件类型分为三大类:同步类事件(如SIGNAL、QUEUE_EVENT)用于任务完成通知,异常类事件(如MEMORY、HW_EXCEPTION)报告错误,拓扑类事件(如NODECHANGE)处理设备变更。该机制通过共享内存和中断实现高效通信,避免CPU轮询开销。后续文章将深入内核实现、Thunk层封装和多队列完成检测实战。

图形/计算GPU的驱动与虚拟化技术分享园地 1307

Linux O(1)调度器

前面我们学习了O(n)调度器的设计,以及它的核心算法。在这里复习下。 O(n)调度器核心: O(n)调度器采用一个runqueue运行队列来管理所有可运行的进程,在主调度schedule函数中会选择一个优先级最高,也就是时间片最大的进程来运行,同时也会对喜欢睡眠的进程做一些补偿,去增加此类进程的时间片。当runqueue运行队列中无进程可选择时,则会对系统中所有的进程进行一次重新计算时间片的操...

半月旋空 2075

58子站安居,经纪人营销管理平台登录接口加密逆向

实战场景password 实战分析 本次要解决的站点依旧来源自78技术人社群,有朋友希望再次说明一下其登录模块的加密参数寻找与逆向逻辑,本文我们就一起分析一下。 站点地址为:vip.anjuke.com/portal/login 通过开发者工具,可以简简单单的寻找到相应的数据。

梦想橡皮擦,专栏100例写作模式先行者,现象级专栏 《Python 爬虫 100 例》作者、《滚雪球学 Python 专栏》原创者 2万+

【Linux】Linux进程(四)Linux O(1)调度器

双“140”队列来回轮转(swap两个指向两个队列的指针expired指针和active指针),就可以实现 “基本公平调度” 了。调度没有直接用某个进程的具体优先级,优先级数字,决定的是进程Taskstruct入队列的问题!在活跃队列的调度周期内,保证按照优先级调度。过期队列的存在,保证,优先级低的进程,可以被调度。在宏观上,所有进程都能被调度;在微观上,优先级高的先调度!unsigned int nr_active(–,一直到减为0,swap交换指针),Linux操作系统中的选择逻辑。

2401_88230254的博客 1331

如何绘制电气绝缘图(GB9706.1-2007和GB9706.1-2020差异)

是用来描述要考虑设备的绝缘状况和它们的值 ,从而便于和相关部门交流和沟通,如权威机构和检测实验室等。本文为绝缘图的实例, 包括所有相关的绝缘路径以及介电强度,爬电距离和电气间隙的值。

学海无涯的专栏 1万+

【DRAM存储器六十六】DDR5介绍--训练相关之CA/CS Training

详述DDR5 CA/CS training过程细节

highman110的博客 199

Linux 进程的一生(二):从 CFS 到 EEVDF,调度器的演进与原理

回顾了 Linux 进程调度器的演进,从早期的 O(n) 调度算法,到 O(1) 调度器,再到目前主流的 CFS,并分析了 EEVDF 在 CFS 之上的改进。

m0_50499434的博客 2012

NLTK中WordNet与同义词处理

通过本教程,学习了如何使用NLTK中的WordNet进行自然语言处理任务。首先介绍了WordNet的基本概念及其在NLTK中的集成使用,接着讲解了如何查找同义词、反义词等词汇关系,并结合实际应用演示了语义相似性计算。这些技能在文本分析、情感分析、信息检索等场景中有广泛应用,可以帮助开发者构建更智能的自然语言处理系统。掌握这些基本操作后,可以进一步探索WordNet的其他高级功能,结合其他NLTK工具进行更复杂的语言分析。

Mr数据杨 474

【Linux进程(四)】深入理解 Linux O(1) 调度器:双队列轮转与进程优先级机制——如何避免进程饥饿,实现公平且高效的进程调度

(–,一直到减为0,swap交换指针),Linux操作系统中的选择逻辑。先拿active指针,找到active——找到现在是在哪一个队列当中,nr_active确定当前有无进程:如果有,查bitmap表,确认数组下标,根据数组下标,找到一个进程。整个过程,时间复杂度几乎是O(1),这就是Linux内核之O(1)调度算法(结构决定算法)。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 1461

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

k8291121的博客 2812

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux2.6 内核进程调度分析

Linux2.6 内核进程调度分析    进程的调度时机与引起进程调度的原因和进程调度的方式有关。在 2.6 中,除核心应用     主动调用调度器之外, 核心还在应用不完全感知的情况下在以下三种时机中启动调度器工作:     1>从中断或系统调用返回到用户态;     2>某个进程允许被抢占 CPU;     3>主动进入休眠状态;        调度策略:     在

张勤一 4072

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux2.6 O(1)调度器

O(1)调度器存在于2.4-2.6版本的内核中。 普通进程和实时进程 Linux中把进程分为普通进程和实时进程两种,实时进程对于系统的响应时间要求很高,因此实时进程的优先级都是要高于普通进程的。 静态和动态优先级 静态和动态优先级的范围都是[100~139],这两个值对于普通进程来说非常重要。 静态优先级(值越小)越高,基本时间片越长,静态优先级越低(值越大),基本时间片越短。这是有一个固定公式进...

程序猿Ricky的日常干货 928

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Linux进程O(1)调度算法,面试必考哦

进程调度有很多方法,这里只讨论Linux下的进程调度,先说下,这个是高端面试必考题,既然我发文了,大家最好看看,而且目前看到的写得最好的文章,推荐给大家。====Linux是一个支持多任务...

嵌入式Linux 898

Linux 2.6 内核 O(1) 调度队列深度解析:为什么它能实现常数时间调度?

在 Linux 2.6 内核之前,进程调度采用的是 O (n) 算法 —— 调度器需要遍历所有就绪进程才能找到优先级最高的那个,进程数量越多,调度效率越低,严重影响多任务场景的性能。而 2.6 内核引入的 O (1) 调度算法,彻底解决了这一痛点,其核心就是设计了高效的调度队列结构,让调度器无论面对多少进程,都能在常数时间内找到最优进程,大幅提升了系统吞吐量。本文从调度队列的核心数据结构、工作流程、优先级管理三个维度,拆解 O (1) 调度队列的设计精髓,帮你理解 “常数时间调度” 的底层逻辑,看透 Lin

会当凌绝顶,一览众山小 2073

进程调度演变过程之O(1)与O(n)调度器 - 进程与线程(十五)

1 调度器概述 任务调度器是操作系统中一个很重要的功能部件,主要功能是把系统中的task调度到各个CPU上去执行,满足如下的性能需求: 调度器必须是公平的:(对于分时的进程,每个任务都应该有机会执行,不能饿死,保证每个进程得到合理的CPU时间) 快速的进程响应时间:(对于交互式进程,需要和用户进行交流,因此对调度延迟比较敏感) 高系统的吞吐量:(对于批处理进程进程,属于那种在后台的默默奉献的,因此它更注重吞吐量的需求) 功耗要小:(对于移动式终端,功耗的需求其实一直以来都没有特别被调度器重视,当然在lin

生活需要深度 1209

Linux的进程调度算法简介

文章目录一、调度算法的原理和分类1.进程调度简介2.按不同需求对调度的进程分类3.调度算法分类二、使用步骤1.引入库1.引入库总结 一、调度算法的原理和分类 1.进程调度简介   进程调度的研究是整个操作系统理论的核心,在多进程的操作系统中,进程调度是一个全局性的、关键性的问题,它对系统的总体设计、系统的实现、功能设置以及各方面的性能都有着决定性的影响。进程运行需要各种各样的系统资源,如内存、文件、打印机和最宝贵的CPU等,所以说,调度的实质就是资源的分配。系统通过不同的调度算法(Scheduling A

无知亦乐 8126
dfh1539
博客等级 码龄11年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值