浅析linux内核调度器与时间系统之等待队列
作者:李万鹏
等待队列实现了在事件上的条件等待:希望等待特定事件的进程把自己放在合适的等待队列,并放弃控制权。因此,等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒他们。
等待队列的数据结构
等待队列头:
这个task_list字段是等待队列链表的头,等待队列是一个双向链表,同步通过lock自旋锁来实现。
等待队列元素:
这个flags字段标示了这个进程是互斥进程还是非互斥进程。那么何为互斥进程,非互斥进程呢?经常会产生一个现象,当某个资源被释放后内核唤醒了所有等待这个资源的进程,结构只有一个进程可以得到这个资源,而其他的进程再次进入睡眠。因此有两种睡眠的进程:互斥进程(等待队列元素的flags字段为1)由内核有选择的唤醒;非互斥进程(等待队列元素的flags字段为0)由内核在事件发生时唤醒。等待访问临界资源的进程就是互斥进程的典型例子。等待相关事件的进程是非互斥的。例如,我们考虑等待磁盘传输结束的一组进程:一旦磁盘传输完成,所有等待的进程都会被唤醒。task字段指向这个等待队列元素对应的进程描述符。func字段表示用什么方式唤醒。等待队列元素都用task_list这个双向链表链接在一起。
等待队列的操作
声明等待队列头:
1)静态声明
DECLARE_WAIT_QUEUE_HEAD(name);
2)动态声明
wait_queue_head_t name;
init_waitqueue_head(&name);
由于静态声明不但包括了对变量的声明还包括了初始化,所以动态声明的分成两个步骤,对动态声明的等待队列元素进行初始化。
声明等待队列元素:
1)静态声明
DECLARE_WAITQUEUE(name, tsk)
这个default_wake_function调用的是try_to_wake_up()。
2)动态声明
wait_queue_t tsk;
init_waitqueue_entry(tsk);
插入等待队列:
1)add_wait_queue()
将等待队列元素插入到等待队列的前面。
2)add_wait_queue_exclusive()
将等待队列元素设置称互斥进程,添加到队列末尾,注意互斥的是需要添加到末尾的,这样唤醒的时候可以选择是唤醒一个还是全部还是nr。
3)prepare_to_wait()
将等待队列元素添加到等待队列,与add_wait_queue()不同点是它可以设置进程的状态。
4)prepare_to_wait_exclusive()
与prepare_to_wait()的区别是prepare_to_wait_exclusive是把非互斥进程添加到等待队列。
删除等待队列:
remove_wait_queue()
把等待队列元素从等待队列删除。
检查队列是否为空:
waitqueue_active()
判断等待队列是否为空。
睡眠函数:
1)sleep_on()
sleep_on()这个函数动态的创建了等待队列元素,并将其添加到等待队列睡眠,然后调度让其他进程执行,如果被唤醒了就从等待队列移除。
2)wait_event()
首先判断条件是否已经成立,如果成立就不用睡眠了。如果不成立创建等待队列元素,将等待队列元素添加到等待队列并设置状态标志。如果此时条件已经满足了就不用调用schedule()让CPU了,可以将等待队列元素从等待队列移除往下执行。
总结一下sleep_on()与wait_event(),如果条件不满足进程会阻塞,被调到等待队列。但是sleep_on()内部没有条件判断,可能在创建等待队列元素并添加到等待队列的时候condition已经为true了,却要调用schedule()将CPU让与别的进程,委屈了!
唤醒函数:
首先看一下唤醒的底层核心函数:
__wake_up_common是唤醒的底层核心函数,调用list_for_each_safe先将非互斥进程唤醒,再根据参数nr_exclusive来决定唤醒互斥进程的数量。从头到尾遍历等待队列,这也是为什么add_wait_queue_exclusive()的时候将互斥进程添加到等待队列末尾而不是头。
1)wake_up()
2)wake_up_nr()
3)wake_up_all()
分享到:
相关推荐
Linux常见驱动源码分析(kernel hacker修炼之道)--李万鹏 李万鹏 IBM Linux Technology Center kernel team 驱动资料清单内容如下: Linux设备模型(中)之上层容器.pdf Linux设备模型(上)之底层模型.pdf Linux...
这本书是“Linux kernel hacker修炼之道”的一部分,通过深入剖析各种常见的驱动源码,帮助读者提升在Linux系统中的驱动开发能力。 在Linux操作系统中,驱动程序是连接硬件与内核的桥梁,它们负责管理和控制硬件...
《常见驱动源码分析(kernel hacker修炼之道)》这本书或课程很可能深入探讨了如何理解和编写这些驱动,旨在帮助开发者提升对Linux内核和驱动编程的理解。在这个过程中,我们将会涉及到几个关键的知识点: 1. **Linux...
如果刚刚对linux的kernel有兴趣,想了解点什么的话,请先看看此书吧,她风趣幽默的介绍了linux的发展趣事,让你开心快乐之余慢慢领会linux的魅力,让你了解学习掌握kernel的方法。其中的很多建议经过我的实践和摸索...
Linux内核驱动是操作系统的核心组件,负责管理硬件设备与CPU之间的通信。驱动程序允许操作系统通过统一的接口来访问硬件设备,而无需关心硬件的物理细节。在Linux系统中,驱动程序通常被划分为内核空间和用户空间两...
有关hacker 的文章和资料分享给大家
ProcessHacker是一款强大的系统信息工具,它提供了进程管理、服务管理、硬件监控、内存查看等多种功能,深受系统...通过下载并使用"processhacker-2.39-bin"压缩包,你将能够亲身体验这些功能并提升你的系统管理技能。
5. **任务调度与队列**:如果 API 需要异步处理代码验证,可以利用 Laravel 的任务调度器 (`app/Console/Kernel.php`) 定时运行任务,或者使用队列 (`queue` 服务提供者) 来处理耗时操作,以避免阻塞主线程。...
Process Hacker是一款针对高级用户的安全分析工具,它可以帮助研究人员检测和解决软件或进程在特定操作系统环境下遇到的问题。除此之外,它还可以检测恶意进程,并告知我们这些恶意进程想要实现的功能。 Process ...
Resource Hacker 可以被用来: 1. 查看 Win32 可执行和相关文件的资源 (*.exe, *.dll, *.cpl, *.ocx),在已编译和反编译的格式下都可以。 2. 提取 (保存) 资源到文件 (*.res) 格式,作为二进制,或作为反编过的译...
Process Hacker是一款强大的系统进程管理工具,并且还可以显示CPU、GPU、IO、内存等相关使用信息。 官网地址:https://processhacker.sourceforge.io/ git地址:https://github.com/processhacker/processhacker
Process Hacker是一款开源、免费且功能强大的系统信息工具,它允许用户查看并管理正在运行的进程、服务、线程以及内存等系统资源。 【描述】"Process Hacker 1.1 PH1" 提示我们这是Process Hacker的早期版本,版本...
The-hacker-playbook3最新版PDF,从某安全群里面分享得到,同步共享给大家
《HackerRank算法挑战解析与实战》 HackerRank是一个全球知名的在线编程竞赛平台,它提供了丰富的算法挑战,旨在帮助开发者提升编程技能、算法理解和问题解决能力。这个名为"HackerRank-Algorithms"的开源项目,...
除了分析数据包本身,我们还需要关注时间戳,看看是否有特定时间点的活动模式,这可能与攻击者的定时触发机制有关。同时,观察数据包间的交互顺序,有时能帮助我们理解攻击的流程。 总的来说,解决"track_hacker...
Process Hacker是一款功能丰富的系统程序,比windows自带的任务管理器功能更强大。用户只要借助该程序就可以方便,快捷地查看相关进程的速度,内存,及模块等等,除此,还可以对相关的进程进行管理工作。
总之,结合HackerRank的算法挑战与Scala语言,开发者可以锻炼编程思维,提升代码质量,更好地应对实际开发中的复杂问题。这个压缩包为你提供了一个宝贵的实践和学习资源,助你在算法的道路上不断进步。