• _wait_event 具体实现过程


    _wait_event 具体实现过程

    分类: 网络文摘 87人阅读 评论(1) 收藏 举报

    来自:http://www.linuxforum.net/forum/showthreaded.php?Board=linuxK&Number=572220

    是不是当前进程要等待某个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。 
    从而可以在下次调度时运行。 

    唤醒是别人的动作。 

  • 相关阅读:
    创建百度地图实例
    IntelliJ IDEA使用(1)——IDEA配置JDK
    IntelliJ IDEA使用(2)——IDEA配置Tomcat
    怎样使用 GitHub?
    IntelliJ IDEA使用(3)——IDEA连接Git
    AS3.0杂记——Dictionary、Object与Array
    AIR文件操作:使用文件对象操作文件和目录 .
    As3.0 TextField
    关于乘机
    Html 嵌入 swf
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124197.html
Copyright © 2020-2023  润新知