Linux-笔记 Linux阻塞与非阻塞IO心得

一、阻塞与非阻塞

        1、阻塞:当需要的资源不可用的时候或不满足运行状态的时候就会挂起等待。

        2、非阻塞:当运行所需资源不可用的时候,轮询查询等待,也可能因为等待超时而放弃。

        3、非阻塞打开文件需要加上O_NONBLOCK。

        4、设备驱动文件默认读取方式是阻塞的。

二、等待队列

        阻塞访问可以让当前不可操作的设备文件进入休眠状态,只有将进程对应等待队列项添加到等待队列头才可以进入休眠状态,等可操作再唤醒,一般在中断里完成唤醒。linux内核使用等待队列来实现阻塞进程唤醒工作。

        1、等待队列头:要使用等待队列就需要初始化一个等待队列头,也可以使用宏DECLARE_WAIT_QUEUE_HEAD一次性完成初始化。

        2、等待队列项:等待队列里面每一个等待进程就是一个队列项。使用宏DECLARE_WAITQUEUE(name,tsk)初始化一个等待队列项。name:等待队列项的名字,tsk:等待队列项属于哪个进程。

        3、添加或移除等待队列头:使用API函数,q分别是要加入或删除的等待队列头, wait分别是要添加或删除的等待队列项。

add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait)
remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)

        4、等待唤醒:当设备可以使用的时候就可以唤醒正在等待队列内休眠的进程了,可使用的函数有两个,分别是

void wake_up(wait_queue_head_t *q)
void wake_up_interruptible(wait_queue_head_t *q)

        q 是要唤醒的等待队列头,这两个函数会将这个等待队列头中的所有进程都唤醒。 wake_up_interruptible 函数只能唤醒处于 TASK_INTERRUPTIBLE 状态的进程。wake_up 函数可以唤醒处于 TASK_INTERRUPTIBLE 和 TASK_UNINTERRUPTIBLE 状态的进程。

        5、等待事件:除了主动唤醒外,也可以设置成等待某个事件触发,也是使用API函数。

wait_event(wq, condition);
wait_event_timeout(wq, condition, timeout);
wait_event_interruptible(wq, condition);
wait_event_interruptible_timeout(wq, condition, timeout);

三、非阻塞之轮询

        1、如果选择非阻塞的方式来访问的话就要使用轮询来处理不能访问的情况。一般采用API函数poll、epoll、slect来处理,应用程序通过这三个函数来查询设备是否可以使用,当应用程序调用三个函数之一的时候驱动程序中的poll函数就会执行。

        2、selcet函数能够监视的文件描述符最大为1024,使用poll函数的话没有最大文件描述符的限制。

        3、selcet与poll都会随着监听的文件增加而使效率减低,而且poll每次需要循环遍历私有文件描述符检查就绪,很不智能,这时候可以使用epoll,它专为处理大并发而准备,一般在网络编程中使用多一些。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值