_wait_event 具体实现过程
来源:互联网 发布:史记哪个版本好 知乎 编辑:程序博客网 时间:2024/04/28 19:11
#define __wait_event(wq, condition)
do {
DEFINE_WAIT(__wait);
for (;;) {
prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);
if (condition)
break;
schedule();
}
finish_wait(&wq, &__wait);
} while (0)
在DEFINE_WAIT(__wait)中
#define DEFINE_WAIT(name)
wait_queue_t name = {
.task = current,
.func = autoremove_wake_function,
.task_list = { .next = &(name).task_list,
.prev = &(name).task_list,
},
}
的autoremove_wake_function:
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
int ret = default_wake_function(wait, mode, sync, key);
if (ret)
list_del_init(&wait->task_list); //注意,等待节点在这里被摘下,并设为空
return ret;
}
prepare_to_wait()和finish_wait()并不是进程睡眠的地方,进程睡眠的地方是schedule()。
prepare_to_wait()只是进行一些链表的操作,以确保自己在等待队列中,不会漏掉事件。
进程在确信自己已经在队列中后,再次检查条件, 这里,如果不检查,可能条件已经满足,直接去睡眠的话,可能再也没有人来唤醒它了。
然后,如果条件不满足,就调用schedule()去睡眠,这里,进程的状态在prepare_to_wait()里设置为TASK_UNINTERRUPTIBLE, 所以,以后调度时就看不到该进程了,因此,该进程将没有机会运行,这就是睡眠。
注意,这里,该进程自己已经无能为力了,因为它自己已经不可能运行了。 只有等待他人来唤醒了。
当条件满足后,会有一个人(或者是其他进程,或者内核本身,等等)来唤醒某个等待队列上的进程。
具体是唤醒全部等待队列中的所有进程,还是只唤醒第一个进程,完全取决于该唤醒者, 等待在队列中的睡眠进程是无能为力的,与它们是没有关系的(呵呵,确切说,有一点关系)。
总是唤醒所有等待该事件的进程并不一定是合适的。比如考虑这样一种情况:如果队列中的多个进程等待的资源是要互斥访问的,一定时间内只允许一个进程去访问的话,这时候,只需要唤醒一个进程就可以了,其他进程继续睡眠。如果唤醒所有的进程,最终也只有一个进程获得该资源,其他进程让需返回睡眠。
因此,等待队列中的睡眠进程可被划分为互斥、非互斥进程。
互斥进程:等待的资源是互斥访问的;互斥进程由内核有选择的唤醒,等待队列项的flag字段为1;
非互斥进程:等待的资源是可多进程同时访问的。非互斥进程在事件发生时,总是被内核唤醒,等待队列元素的flag字段为0。
唤醒者通常调用__wake_up_common(),这样,依次取下等待队列中的__wait_queue_t结构, 调用该睡眠进程设置的func函数,即这里的autoremove_wake_function(), 将该进程的状态重新设置为RUNNING。
注意,此时该睡眠进程并不会立刻执行,只有等到下次调度的时候,该进程才有机会运行, 即醒来了。醒来是从schedule()回来,继续运行__wait_event()
总结一下, 睡眠是自己设置好进程状态(TASK_UNINTERRUPTIBLE,等等),加入等待队列, 并调用schedule()去睡眠。 睡眠是自己的动作。
唤醒是别人发现条件满足,调用__wake_up_common(),将睡眠进程从等待队列取下, 调用该睡眠进程设置的唤醒func,重新设置该睡眠进程为RUNNING。 从而可以在下次调度时运行。 唤醒是别人的动作。
- _wait_event 具体实现过程
- _wait_event 具体实现过程
- _wait_event 具体实现过程
- _wait_event 具体实现过程
- _wait_event 具体实现过程
- _wait_event 具体实现过程
- fd_set的具体实现过程
- fastText具体代码实现过程
- sql语句实现的具体过程
- 解析cookie欺骗实现过程及具体应用
- 解析Cookie欺骗实现过程及具体应用[zt]
- 解析Cookie欺骗实现过程及具体应用
- 解析Cookie欺骗实现过程及具体应用
- 解析Cookie欺骗实现过程及具体应用
- 个人对objc_msgSend 函数具体实现过程解读
- shell具体执行过程及自主实现shell解释器
- 特征描述子(-)—HOG具体实现过程
- 【算法入门】A* 寻路算法具体过程及实现
- facebook login官方文档iOS
- iOS集成facebook SDK官方文档
- ASP.NET 5系列教程 (五):在Visual Studio 2015中使用Grunt、Bower开发Web程序
- Tomcat8.X安装心得
- des工具类,这样就够了,嘿嘿
- _wait_event 具体实现过程
- 转载-不安装oracle客户端也可以使用pl/sql developer
- java httpURL连接远程服务器并返回数据(httpurlconnection)
- 登陆验证姓名密码,自动登录 ,get获取服务器数据,显示表格形式到界面
- Stanford机器学习课程笔记——LR的公式推导和过拟合问题解决方案
- 常用 Java 静态代码分析工具的分析与比较
- 几种常用的视频接口
- 我的奋斗,是为了和你坐在一起喝咖啡?
- 第三章 Hadoop2.x应用开发step by step——HDFS