Linux设备驱动模板:等待队列(2)

linux中最简单的休眠方式: 
wait_event(queue, condition)  /* 进程将被置于非中断休眠(uninterruptible sleep)*/
wait_event_interruptible(queue, condition) /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/
wait_event_timeout(queue, condition, timeout)    /*等待限定时间jiffy,condition满足其一返回0*/ 
wait_event_interruptible_timeout(queue, condition, timeout) 

queue是等待队列头,传值方式

condition是任意一个布尔表达式,在休眠前后多次对condition求值,为真则唤醒

唤醒进程的基本函数:
void wake_up(wait_queue_head_t *queue);     /*唤醒等待在给定queue上的所有进程*/
void wake_up_interruptible(wait_queue_head_t *queue); 

总结一下Linux等待等列用法:

1、定义:wait_queue_head_t my_queue;
2、初始化 init_waitqueue_head(&my_queue);
3、在一个函数里面等待:wait_event_interruptible(queue, condition) ;(别在中断里面调用)
4、在另一个函数里面唤醒:wake_up_interruptible(wait_queue_head_t *queue); (这个可以在中断调用,去唤醒别的进程,特别是DMA操作等)

最后附上一个小的模板:

struct xxx_dev     {         struct cdev cdev;         wait_queue_head_t r_wait;         wait_queue_head_t w_wait;         bool have_data;   };         struct xxx_dev *xxx_devp;      static ssize_t xxx_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)   {       struct xxx_dev *dev = filp->private_data;       ......       /* 注意:使用的while,而不是if */       while(!have_data)       {           /* 如果用户设置了非阻塞的方式,则不需要调用等待队列 */           if (filp->f_flags & O_NONBLOCK)               return -EAGAIN;           /* interruptible:进程的唤醒有可能是其他信号 */           else               wait_event_interruptible(xxx_devp->r_wait,have_data);       }       ......   }      static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)   {       struct xxx_dev *dev = filp->private_data;       ......       have_data = true;       wake_up_interruptible(&xxx_devp->r_wait);    /* 唤醒等待队列 */       ......   }      static int memdev_init(void)   {       ......       xxx_devp = kmalloc(sizeof(struct xxx_dev), GFP_KERNEL);       ......       xxx_devp->have_data = false;       init_waitqueue_head(&xxx_devp->r_wait);  /*初始化读等待队列头 */       init_waitqueue_head(&xxx_devp->w_wait);  /*初始化写等待队列头 */       ......   }  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwgsgs.html