Linux内核开发之阻塞/非阻塞IO----等待对列

2024-04-22 17:38

本文主要是介绍Linux内核开发之阻塞/非阻塞IO----等待对列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

十一过后..

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

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

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

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

“呵呵,有需求才会有进步”我哈哈大笑道,“要不这样吧,看这样子,正好给你说说有关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(),而是亲自进行进程的状态改变和切换。

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


这篇关于Linux内核开发之阻塞/非阻塞IO----等待对列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926436

相关文章

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

Linux使用scp进行远程目录文件复制的详细步骤和示例

《Linux使用scp进行远程目录文件复制的详细步骤和示例》在Linux系统中,scp(安全复制协议)是一个使用SSH(安全外壳协议)进行文件和目录安全传输的命令,它允许在远程主机之间复制文件和目录,... 目录1. 什么是scp?2. 语法3. 示例示例 1: 复制本地目录到远程主机示例 2: 复制远程主