zoukankan      html  css  js  c++  java
  • Linux使用wake_up_interruptible()唤醒注册到等待队列上的进程

    http://blog.sina.com.cn/s/blog_4770ef020101h48l.html
     
     
    功能:唤醒注册到等待队列上的进程

    原型
        #include
        void wake_up_interruptible (wait_queue_head_t *q);

    说明
        唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态

    变量
    q :  等待队列变量指针。

     

     

       最近在学习驱动时有一个问题始终想不明白,为什么wait_event_interruptible(button_waitq, ev_press)需要一个全局变量来记住中断的发生?
    在驱动中实现读取操作时,使用了
    1. wait_event_interruptible(button_waitq, ev_press);
    在中断函数中使用了如下语句唤醒:
    1. ev_press = 1;  //表示中断发生了
    2. wake_up_interruptible(&button_waitq);  //唤醒休眠的进程
    这样的话,中断能正确读取到。我分别尝试了屏蔽ev_press = 1;和wake_up_interruptible(&button_waitq);代码,发现中断不能正常产生。

    查找资料,阅读源代码。
    1. #define wait_event_interruptible(wq, condition)          
    2. ({                                                      
    3.     int __ret = 0;                                      
    4.     if (!(condition))                                    
    5.         __wait_event_interruptible(wq, condition, __ret);
    6.     __ret;                                              
    7. })
    1. #define __wait_event_interruptible(wq, condition, ret)                        
    2. do {                                                                        
    3.         DEFINE_WAIT(__wait);                                                
    4.                                                                         
    5.         for (;;) {                                                        
    6.                 prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);        
    7.                 if (condition)                                                
    8.                         break;                                                
    9.                 if (!signal_pending(current)) {                                
    10.                         schedule();                                        
    11.                         continue;                                        
    12.                 }                                                        
    13.                 ret = -ERESTARTSYS;                                        
    14.                 break;                                                        
    15.         }                                                                
    16.         finish_wait(&wq, &__wait);                                        
    17. } while (0)
    __wait_event_interruptible()首先定义并初始化一个wait_queue_t变量__wait,其中数据为当前进程current,并把__wait入队。
        在无限循环中,__wait_event_interruptible()将本进程置为可中断的挂起状态,反复检查condition是否成立,如果成立则退出,如果不成立则继续休眠;条件满足后,即把本进程运行状态置为运行态(此时如果不执行下面的函数 wake_up_interruptible,上面wait_event_interruptible还会继续休眠),并将__wait从等待队列中清除掉,从而进程能够调度运行。如果进程当前有异步信号(POSIX的),则返回-ERESTARTSYS。
    1. //唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    创建虚拟桌面的代码(重启桌面进程)(使用GetThreadDesktop,CreateDesktop,SetThreadDesktop等函数)
    SEH and C++ Exceptions,自定义CSeException
    VC自动与Internet时间服务器同步更新
    VS2005 检测内存泄漏的方法(转载)
    VC判断当前用户有无Administrator的权限(用EqualSid API函数判断与Admin是否在一个组的Sid)
  • 原文地址:https://www.cnblogs.com/jingzhishen/p/4208501.html
Copyright © 2011-2022 走看看