Linux设备驱动程序之阻塞/非阻塞IO----等待对列

来源:互联网 发布:淘宝卖家旺旺名是什么 编辑:程序博客网 时间:2024/06/11 03:04

十一过后..

小王也刚好即将大学毕业,现在要开始写简历,投简历,找工作了。

到了家工作单位,小王欣喜若狂,可再一看,心都凉了半截..

“咋了,小王,看你找工作,我都来了帮你大气,怕什么,不就人多点吗..”看着排到电梯口的长龙,我说(其实,我心里也害怕,可也不能说出来不是)。

“不是,你不知道,我并不怕面试上有问题,有你在,技术上还是问题吗,不相信自己还不相信你啊,我主要是怕连面试的机会都没有,你看那么多人,不知道要排到哪里去了,你说每年都这样,那些人力主管部门的咋也不想个好办法来改善一下..”小王抱怨道。

“呵呵,有需求才会有进步”我哈哈大笑道,“要不这样吧,看这样子,正好给你说说有关Linux设备驱动程序中的阻塞/非阻塞IO,说不定,你一会儿面试时刚好遇到,就不用愁了..”

“好好,太好了,找你算没白找..”

看到小王兴致来了,我也卖个关子,顿口气说道:”下面请听----Linux设备驱动程序之阻塞/非阻塞IO”

阻塞:顾名思义,就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移

走,直到等待的条件满足。

非阻塞:就是反过来,进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直到可以进行位置。

“小王,明白了没这两个基本的概念,比如就像今天的面试就是一个阻塞的问题”我补充到,“当然,是不是说非阻塞一定要不非阻塞好,答案是否定的,比如如果设备驱动不阻塞,则用户想获取设备操作就只能不断的用cpu查询(当然不可能放弃了),很显然这又会无谓的消耗CPU资源。在阻塞访问就不存在这样的问题了,不能获取资源的进程进入休眠,它将CPU资源让给了其他进程”。

“听你这么一说我, 再结合今天这架势,我是明白了,只是你刚才说的休眠什么的…那是不是如果条件满足了,再整个休眠唤醒 什么的..”小王打岔道。

“不错啊, 有点我当年的风范,懂得触类旁通了,确实这样,这样,我给你两段代码,亲身感受一下吧”

阻塞地都取串口一个字符

非阻塞地都取串口一个字符

char buf;
fd = open ("/dev/ttys ",O_RDWR);
.. ..
res = read (fd,&buf,1); //当串口上有输入时才返回
if (res == 1)
{
printf ("%c/n ",buf);
}char buf;
fd = open ("/dev/ttys ",O_RDWR | O_NONBLOCK);
.. ..
while (read (fd,&buf,1) !=1); //当串口上无输入也返回,
//以要循环尝试读取串口

printf ("%c/n ",buf);
L
现在我们有了阻塞的方式读取,那么阻塞的进程因为没有获得资源会进入休眠状态,现在就要聊聊有关唤醒的事了。在Linux设备驱动中,可以使用等待队
列(wait queue)来实现阻塞进程的唤醒.等待队列能够用于实现内核中的异步事件通知机制。Linux提供了有关等待队列的操作:
1) wait_queue_head_t my_queue;    //定义等待队列头
2) init_waitqueue_head(&my_queue);    //初始化队列头
   如果觉得上边两步来的麻烦,可以直接使用DECLARE_WAIT_QUEUE_HEAD(name)
3) DECLARE_WAITQUEUE(name,tsk);    //定义等待队列
4) void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
   void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

用于将等待队列wait添加到等待队列头指向的等待队列链表中 。

5) wait_event(queue, conditon);

wait_event_interruptible(queue, condition);//可以被信号打断

wait_event_timeout(queue, condition, timeout);

wait_event_interruptible_timeout(queue, condition, timeout);//不能被信号打断

queue:作为等待队列头的等待队列被唤醒

conditon:必须满足,否则阻塞

timeout和conditon相比,有更高优先级

6) void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

上述操作会唤醒以queue作为等待队列头的所有等待队列中所有属于该等待队列头的等待队列对应的进程。

7) sleep_on(wait_queue_head_t *q);

interruptible_sleep_on(wait_queue_head_t *q);

sleep_on作用是把目前进程的状态置成TASK_UNINTERRUPTIBLE,并定义一个等待队列,之后把他附属到等待队列头q,直到资源可用,q引导的等待队列被唤醒。interruptible_sleep_on作用是一样的, 只不过它把进程状态置为TASK_INTERRUPTIBLE.

这两个函数的流程是首先,定义并初始化等待队列,把进程的状态置成TASK_UNINTERRUPTIBLE或TASK_INTERRUPTIBLE,并将对待队列添加到等待队列头。

然后通过schedule(放弃CPU,调度其他进程执行。最后,当进程被其他地方唤醒,将等待队列移除等待队列头。

在Linux内核中,使用set_current_state()和__add_wait_queue()函数来实现目前进程状态的改变,直接使用current->state = TASK_UNINTERRUPTIBLE

类似的语句也是可以的。

因此我们有时也可能在许多驱动中看到,它并不调用sleep_on或interruptible_sleep_on(),而是亲自进行进程的状态改变和切换。

“小王,听了这么多你心里有个大致的底了没,如果考官问道这方面的问题,应该挺顺利的,现在时间来不及了,晚点我给你来个例子,你看看就可以了,瞧,马上到你了,赶快准备一下,祝你好运哦..”

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝虚拟恶意退款怎么办 淘宝虚拟单退款怎么办 虚拟物品被骗了怎么办 网络选修课挂了怎么办 美团商家退出怎么办 卖家版运费险太贵了怎么办 美瞳没有客源怎么办 购物车满了怎么办 手机程序无响应怎么办 三星手机无响应怎么办 游戏无响应了怎么办 手机百度无响应怎么办 新手机响应慢怎么办 vivo手机无响应怎么办 vivo软件无响应怎么办 退货商家不处理怎么办 淘宝页面变小了怎么办 淘宝卖家让微信交易被骗怎么办 苹果下载特别慢怎么办 淘宝没有支付宝怎么办 淘宝买东西限购怎么办 淘宝被别人登录怎么办 淘宝被厂家投诉怎么办 买家退货说是假货怎么办 同行给差评怎么办 被买家举报了怎么办 淘宝商品被屏蔽怎么办 电脑处于离线状态怎么办 计算机处于离线状态怎么办 交易猫安全提醒怎么办 网吧进游戏代码怎么办 车票冲突买不了怎么办 苹果8淘宝打不开怎么办 我的淘宝打不开怎么办 福袋不支持退货怎么办 不支持跨区下单怎么办 支付宝被占用怎么办 淘宝东西失效了怎么办 访客突然下降了怎么办 淘宝店铺广告违规怎么办 苹果手机网速差怎么办