_wait_event 具体实现过程
来源:互联网 发布:冰寒扒皮知乎 编辑:程序博客网 时间:2024/06/09 13:47
是不是当前进程要等待某个condition,然后就把它加到这个等待这个condition的wq中
_wait_event是当前进程调用它,也就是在宏DEFINE_WAIT(_wait)中的_wait就是把当前进程设置成_wait加到等待队列里,
以上基本正确
如果condition发生,是这个进程被唤醒设置成running而不是整个等待队列wq被唤醒?
如果conditon没有发生,还在prepare_to_wait里,这里保证了_wait不会被第二次加到等待队列中,但是第一次循环是加入了。finish_wait是将_wait移除。
那么在DEFINE_WAIT中的func设置成autoremove_wake_function意义何在?
prepare_to_wait()和finish_wait()并不是进程睡眠的地方,进程睡眠的地方是schedule().
prepare_to_wait()只是进行一些链表的操作,以确保自己在等待队列中,不会漏掉事件。
进程在确信自己已经在队列中后,再次检查条件,
这里,如果不检查,可能条件已经满足,直接去睡眠的话,可能再也没有人来唤醒它了。
然后,如果条件不满足,就调用schedule()去睡眠,
这里,进程的状态在prepare_to_wait()里设置为TASK_UNINTERRUPTIBLE,
所以,以后调度时就看不到该进程了,因此,该进程将没有机会运行,这就是睡眠。
注意,这里,该进程自己已经无能为力了,因为它自己已经不可能运行了。
只有等待他人来唤醒了。
当条件满足后,会有一个人(或者是其他进程,或者内核本身,等等)来唤醒某个等待队列上的进程。
具体是唤醒全部等待队列中的所有进程,还是只唤醒第一个进程,完全取决于该唤醒者,
等待在队列中的睡眠进程是无能为力的,与它们是没有关系的(呵呵,确切说,有一点关系)。
唤醒者通常调用__wake_up_common(),这样,依次取下等待队列中的__wait_queue_t结构,
调用该睡眠进程设置的func函数,即这里的autoremove_wake_function(),
将该进程的状态重新设置为RUNNING,
注意,此时该睡眠进程并不会立刻执行,只有等到下次调度的时候,该进程才有机会运行,
即醒来了。醒来是从schedule()回来,继续运行__wait_event()
总结一下,
睡眠是自己设置好进程状态(TASK_UNINTERRUPTIBLE,等等),加入等待队列,
并调用schedule()去睡眠。
睡眠是自己的动作。
唤醒是别人发现条件满足,调用__wake_up_common(),将睡眠进程从等待队列取下,
调用该睡眠进程设置的唤醒func,重新设置该睡眠进程为RUNNING。
从而可以在下次调度时运行。
唤醒是别人的动作。
wait_event_interruptible(queue_wait,condition)。该函数修改task的状态为TASK_INTERRUPTIBLE,意味着改进程将不会继续运行直到被唤醒,然后被添加到等待队列wq中。
在wait_event_interruptible()中首先判断condition是不是已经满足,如果是则直接返回0,否则调用__wait_event_interruptible(),并用__ret来存放返回值
---------------------------------------------------------------
#define wait_event_interruptible(wq, condition)__wait_event_interruptible(wq, condition, __ret);\ \
({\
int __ret = 0; \
if (!(condition)) \
__ret; \
})
wait_event_interruptible() --> __wait_event_interruptible()
__wait_event_interruptible()首先定义并初始化一个wait_queue_t变量__wait,其中数据为当前进程current,并把__wait入队。
在无限循环中,__wait_event_interruptible()将本进程置为可中断的挂起状态,反复检查condition是否成立,如果成立
则退出,如果不成立则继续休眠;条件满足后,即把本进程运行状态置为运行态,并将__wait从等待队列中清除掉,从而进程能够调度运行。如果进程当前有
异步信号(POSIX的),则返回-ERESTARTSYS。
- _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* 寻路算法具体过程及实现
- 利用DTGridView实现横向滚动的tableview
- linux列出一个目录及其子目录下面的某种类型的文件
- 头文件
- Advanced PHP Programming -- "require_once(Console/getopt.php) : failed to open stream" P129
- 重新规划你的人生——九条必看的职业规划箴言
- _wait_event 具体实现过程
- tmp分区大小不足的情况下,重新设定Linux 临时分区
- 使用AIDL实现进程间的通信 (转载liuhe688)
- qvfb怎么用
- 输入时间时,需验证时间有效性
- 估计子的性能——从最大似然估计到方差定义式为什么以n-1作为分母
- Java中getResourceAsStream的用法
- Python执行系统命令的方法 os.system(),os.popen(),commands
- 利用ASIHTTPRequest 发送数据到(新浪微博)以及新浪API Oauth认证