void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry) { unsigned long flags; //设置当前进程状态为 running 状态 __set_current_state(TASK_RUNNING); /* *若wait条目还在等待队列头上挂着,就将其摘取下来。由前面的唤醒回调函数可知, * 对于实际唤醒的entry已经摘下来...
跳出循环后,调用 "finish_wait()",将状态重置为“运行态”,并从 wait queue 移除,等待的过程彻底结束。 voidfinish_wait(structwait_queue_head*wq_head,structwait_queue_entry*wq_entry){__set_current_state(TASK_RUNNING);list_del_init(&wq_entry->entry);... 本文开头提到“众多的上层实现依赖于此”,...
当进程被唤醒后,一般会直接调用finish_wait函数,将进程的状态重新设置为running,并将该进程对应的等待队列项从等待队列中删除: voidfinish_wait(structwait_queue_head *wq_head,structwait_queue_entry *wq_entry) { unsignedlongflags; __set_current_state(TASK_RUNNING);/*¦* We can check for list empti...
当wake up的时候,阻塞在wq(也可以说阻塞在wait_event处)等待队列头上的进程,再次得到运行,接着执行schedule()后面的代码,这里,显然是个循环,prepare_to_wait再次设置当前进程为睡眠状态,然后判断条件是否满足, 满足就退出循环,finish_wait将当前进程恢复到TASK_RUNNING状态,也就意味着阻塞解除。不满足,继续睡下去。如...
wake_up_interruptible:对应 wait_event_interruptible 版本的 wake up wake_up_interruptible_sync:保证 wake up 的动作原子性,wake_up 这个函数,很有可能函数还没执行完,就被唤起来进程给抢占了,这个函数能够保证 wak up 动作完整的执行完成。 其他的也是与对应阻塞接口对应的。
介绍这几个函数,不得不先介绍等待队列wait_queue_head_t 等待队列用于使得进程等待某一特定事件的发生,无需频繁的轮询,进程在等待周期中睡眠,当时间发生后由内核自动唤醒。 等待队列 (一)数据结构 等待队列结构如下,因为每个等待队列都可以再中断时被修改,因此,在操作等待队列之前必须获得一个自旋锁。
#include <linux/wait.h> 1. 定义和初始化等待队列头(workqueue): 静态的,用宏: #define DECLARE_WAIT_QUEUE_HEAD(name) \ wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) 1. 2. 动态的,也是用宏: #define init_waitqueue_head(q) \ ...
1// ${linux_source}/include/linux/wait.h 2#defineDEFINE_WAIT(name) 3wait_queue_t name = { 4.private = current, 5.func = autoremove_wake_function, 6.task_list = LIST_HEAD_INIT((name).task_list), 7} prepare_to_wait 和 finish_wait 源码如下: ...
wait_queue_t wait; 4.初始化等待队列,将当前进程添加到这个容器中 init_waitqueue_entry(&wait, current); 说明:current是内核的一个全局变量,用来记录当前进程,内核对于每一个进程,在内核空间都有一个对应的结构体struct task_struct,而current指针就指向当前运行的那个进程的task_struct结构体,你可以通过current...
下一个可执行进程切换完毕后执行finish_task_switch中,会调用put_task_struct函数将前一个退出进程的进程引用计数-1,但是回头看一下fork函数就可以发现,进程在初始化时,设置引用计数为2,因此如果进程的exit_state是ZOMBIE,那么此时task_struct仍然没有被释放,实际上会在do_wait中由父进程释放一次后,引用计数变为0,...