linux驱动开发-阻塞非阻塞

从并发的需要,引起的竞争状态,到解决竞争状态的方法机制:
禁止中断
信号量
自旋锁
Completion
原子操作


目标:
掌握进程睡眠和唤醒的方法 
掌握阻塞型I/O的实现方法 
掌握poll/select系统调用的实现方法 

阻塞:进程休眠和唤醒
非阻塞:非阻塞IO  selec poll系统调用


休眠的意义?
从调度器的运行队列-》某个等待队列


唤醒等待队列可能发生的情况
当调用wake_up时,所有等待在该队列上的进程都被唤醒,并进入可运行状态
如果只有一个进程可获得资源,此时,其他的进程又将再次进入休眠
如果数量很大,被称为”疯狂售群”


独占等待
与普通休眠的不同
等待队列入口设置了WQ_FLAG_EXCLUSIVE标志时,则会被添加到等待队列的尾部。而没有这个标志的入口会被添加到头部。
在某个等待队列上调用wake_up时,它会在唤醒第一个具有WQ_FLAG_EXCLUSIVE标志的进程之后停止唤醒其他进程。
使进程进入独占等待函数:

-------------------poll函数-----------------------
void poll_wait(struct file *,wait_queue_head_t *,poll_table *);
向poll_table添加一个等待队列

如果当前没有文件描述符可用来执行I/0,则内核将使进程在传递到该系统调用的所有文件描述符对应的等待队列上等待。
http://blog.chinaunix.net/uid-30558445-id-5524932.html  poll函数调用过程 描述简单。


poll_wait只是把本进程挂入某个队列,应用程序调用poll > sys_poll > do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll

函数后,再调用schedule_timeout进入休眠。如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让

驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:chedule_timeout(__timeout),只是要休眠__time_out这段时间。
示例:
    static unsigned int xxx_poll(struct file *filp,poll_table *wait)
    {
        struct xxx_pipe *dev = filp->private_data;
        unsigned int mask=0;

        down(&dev->sem);
            poll_wait(filp,&dev->inq,wait);
            poll_wait(filp,&dev->outq,wait);
           if(read_buffer_not_empty) //如果接收buffer不为空,可读
            mask |= POLLIN | POLLRDNORM;     /*可读取*/
            if(write_buffer_not_full)      //如果写buffer不满,可写        
            mask |= POLLOUT | POLLWRNORM;   /*可写入*/
        up(&dev->sem);
        return mask;
    }


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值