Linux内核与驱动面试经典“小”问题集锦(1)

笔者混迹职场这么多年来换了不少工作。头些年做的是单片机工程师,后来转入了Linux。转入Linux后,一开始做BSP和驱动工程师(当然后来应用工程师的事也没少干),近几年来专做了Linux内核与系统工程师。由打转入Linux后,经过了大大小小无数次与其相关的面试、笔试,其中绝大多数都是与Linux驱动和内核相关的。在此,我把一些反复被问到过的、印象深刻的内核与驱动方面的相对“小”一些问题的问与答写这里,以供后来者了解和学习,如果能够帮助大家在今后的面试中提高通过的概率,个人觉得这也是一件“勿以善小而不为”(原本是想写“善莫大焉”来着,但个人觉得远远不够)的事情。

所谓“小”问题,并不意味着是简单问题、比较好回答的问题,更不代表是不重要的问题。而是指方面比较小,几句话就能够说清楚的问题、无需发表长篇大论。但不要小看问题“小”,往往这些题才是面试官需要透过其而看到你的基本功和功力的,对于这些问题如果能够回答出来、哪怕能够回答对一部分,面试官对于你的印象分也是能够大大提高的。

在此特别强调一点,对于以下各个问题,希望大家能够不光知其然、更要知其所以然。也就是说别光看问题和答案,要真正掌握其背后的原理。否则面试的时候,面试官一旦深入展开,就“露陷”了。

书归正传,开始列出各个问题与答案及解析。

注:下边问与答中带有“()”标记的是对于此题的分析,而非实际要回答出来的。

问题1

问:Linux内核中的锁都有哪些?各自的使用场景是什么?有什么区别和联系?

备注:这道题在百度、蔚来以及其它几家小公司面试时被问到过。

答:

(1)Linux内核中有许多不同类型的锁,这些锁的类型包括自旋锁(spin lock)信号量(semaphore)互斥锁(mutex)读写锁(rwlock)、顺序锁(seqlock)等。(这个等包括完成量原子操作等。)

(这里,不要求你全说出来,只要能说出自旋锁、信号量、互斥锁就可以了。当然,英文也不要求你必须说出来,但你得知道,别后续面试官一说英文,你完全“懵逼”就行。)

(2)(实际上后两问基本上是一回事。要想回答这些锁机制各自的使用场景以及区别和联系,先得知道各个锁的作用)。

  • 自旋锁(spin lock)

自旋锁是一种典型的对临界资源进行互斥访问的手段,其名称来源于它的工作方式。

为了获得一个自旋锁,在某CPU上运行的代码需要先执行一个原子操作,该操作测试并设置(Test-And-Set)某个内存变量。由于它是原子操作,因此在该操作完成前,其它执行单元不可能访问这个内存变量。如果测试结果表明已经空闲,则程序获得此自旋锁并继续执行;如果测试结果表明锁仍被占用,则程序将在一个小的循环内重复这个“测试并设置”操作,即进行所谓的“自旋”(说白了就是“原地打转”)。

当自旋锁的持有者通过重置该变量释放这个自旋锁后,某个等待的“测试并设置”操作向其调用者报告锁已释放。

(当然,不要求全说出来,说出核心意思即可。下同。)

  • 信号量(semaphore)

信号量是操作系统中最典型的用于同步和互斥的手段,信号量的值可以是0、1或者n。信号量与操作系统中的经典概念PV原语(PV操作)对应。

由于新版本的Linux内核倾向于直接使用mutex作为互斥手段,因此信号量用作互斥不再被推荐使用。

  • 互斥锁(mutex) 

尽管信号量已经可以可以实现互斥的功能,但“正宗”的mutex在Linux内核中还是真实地存在着。

互斥锁是最基本的锁类型,也是最常用的锁,在Linux内核中使用较为广泛。它是一种二元锁,只能同时有一个执行单元持有该锁。当一个线程请求该锁时,如果锁已被占用,则该执行单元会被阻塞直到锁被释放。互斥锁可以保护临界资源,使得在某个时刻只有一个任务可以访问它。

互斥锁的实现使用了原子操作,因此它的性能比较高,但也容易出现死锁情况。

  • 读写锁(rwlock)

自旋锁不关心锁定的临界区究竟在进行什么操作,不管是读还是写,它都一视同仁。即便是多个执行单元同时读取临界资源也会被锁住。实际上,对共享资源并发访问时,多个执行单元同时读取也是不会有问题的,这就产生了自旋锁的衍生锁读写自旋锁,简称读写锁。

读写锁是一种比自旋锁粒度更小的锁机制,它保留了“自旋”的概念,可允许读的并发,但在写操作方面,最多只能有一个写执行单元。当然,读和写也不能同时进行。

  • 顺序锁(seqlock)

顺序锁是对读写锁的一种优化。若使用顺序锁,读执行单元不会被写执行单元阻塞。也就是说,读执行单元在写执行单元对被顺序锁保护的共享资源进行写操作时,仍然可以继续读,而不必等待写执行单元完成写操作;而写执行单元也不需要等待所有的读执行单元完成读操作后才去进行操作。

但是,写执行单元与写执行单元之间仍然是互斥的,即如果有写执行单元在进行写操作,其它写执行单元必须自旋在那里,直到写执行单元释放了顺序锁。

对于顺序锁而言,尽管读写之间不相互排斥,但如果读执行单元在读操作期间,写执行单元已经完成了写操作,那么读执行单元必须重新读取数据,以确保得到的数据是完整的。因此在这种情况下,读端可能反复读多次同样的区域才能读到有效的数据。

经过上述对于各个锁的介绍,接下来可以回答问题了。这里以自旋锁和互斥锁的比较为例来进行解答。而这两个锁的异同其实才是面试官所需要的答案。

自旋锁和互斥锁都是解决互斥问题的基本手段,面对特定的情况(场景),选择的依据是临界区的性质和系统的特点。

从严格意义上来说,互斥锁和自旋锁属于不同层次的互斥手段,前者的实现依赖于后者。在互斥锁本身的实现上,为了保证其结构存取的原子性,需要自旋锁来互斥。因此,自旋锁属于更底层的手段。

互斥锁(也称互斥体)是进程级的,用于多个进程之间对资源的互斥,虽然也是在内核中,但是该内核执行路径是以进程的身份、代表进程来争夺资源的。如果竞争失败,会产生进程上下文切换,当前进程进入睡眠状态,CPU将运行其它进程。鉴于进程上下文切换的开销也很大,因此,只有当进程占用资源时间较长时,使用互斥锁才是比较好的选择。

当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它可以节省上下文切换时间。但是CPU得不到自旋锁会在那里空转,直到其它执行单元解锁为止,所以要求锁不能在临界区里长时间停留,否则会降低系统效率。

由此,可以总结出自旋锁和互斥锁选用的三项原则:

1)当锁不能被获取到时,使用互斥锁的开销是进程上下文切换时间,使用自旋锁的开销是等待获取自旋锁(由临界区执行时间决定)。若临界区比较短小,宜使用自旋锁;若临界区较长,应使用互斥锁。

2)互斥锁所保护的临界区可包含可能引起阻塞的代码;而自旋锁则绝对要避免包含可能引起阻塞的代码的临界区。因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图获取此自旋锁,死锁就会发生。

3)互斥锁存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断(不可重入)情况下使用,则在互斥锁和自旋锁之间只能选择自旋锁。当然,如果一定要使用互斥锁,则只能通过mutex_trylock()方式进行,不能获取就立即返回以避免阻塞。

参考资料:

《Linux设备驱动开发详解 —— 基于最新的Linux 4.0内核》 宋宝华 编著,机械工业出版社

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++阶梯之类与对象(一)

目录 1.面向过程与面向对象 c语言的视角: c的视角 2. 类的引入 3. 类的定义 3.1 类的两种定义方式 3.2 成员变量如何命名 4. 类的访问限定符与封装 4.1 访问限定符 4.2 封装 5. 类的作用域 6. 类的实例化 7. 类对象模型 7.1 怎么计算一个类对象的…

redis布隆过滤器(Bloom)详细使用教程

文章目录 布隆过滤器1. 原理2. 结构和操作3. 特点和应用场景4. 缺点和注意事项 应用-redis插件布隆过滤器使用详细过程安装以及配置springboot项目使用redis布隆过滤器下面是布隆过滤器的一些基础命令 扩展 布隆过滤器 Bloom 过滤器是一种概率型数据结构,用于快速判…

解决方案必备PPT网站

解决方案工作过程中,必备的技能: 1.word排版(投标文件的编写等...) 2.PPT汇报(如何快速找到你需要的模版,并且输入汇报资料) 免费(免费使用,同时也不需要注册) 1.优…

【ETOJ P1013】小e的书架 题解(二分查找)

题目描述 小e要把 n n n 本规格相同的书放进书架里,对于每一本书,他可以横着放也可以竖着放(不能斜着放)。 书的宽度为 1 1 1,高度为 h h h,书架的高度为 t t t,意味着如果你横着放&#…

CUDA/TensorRT部署知识点

CUDA相关: 1、CUDA核函数嵌套核函数的用法多吗? 答:这种用法非常少,主要是因为启动一个kernel本身就有一定延迟,会造成执行的不连续性。 2、如下代码里的 grid/block 对应硬件上的 SM 的关系是什么? 答:首先需要理解grid/block是软件层的概念,而SM是硬件层的概念。所…

前端学习之路(4) vue2和vue3的区别

一. 根节点不同 vue2中必须要有根标签vue3中可以没有根标签,会默认将多个根标签包裹在一个fragement虚拟标签中,有利于减少内存。 二. 组合式API和选项式API 在vue2中采用选项式API,将数据和函数集中起来处理,将功能点切割了当…

C语言如何控制输出最⼩宽度?

一、问题 数据的美观性问题,不仅需要使⽤标志进⾏占位,还需要对宽度等进⾏控制。那么如何控制宽度呢? 二、解答 控制宽度的问题,处理起来其实很简单。如果输出数据的实际位数⼤于定义的宽度, 则按实际位数输出&#x…

springboot151基于web的人力资源管理系统的设计与实现

人力资源管理系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,员工信息因为其管理内容繁杂,管理数量繁…

SSH免密切换服务器案例-ssh协议(公钥和私钥)

公钥和私钥理解 公钥提供加密,私钥解密,公钥可以共享,私钥不可以。举例公钥相当于锁头,可以给别人用,钥匙相当于私钥,只能开自己发出去的锁头,也就是私钥和公钥成对,私钥只能解密对…

~小青蛙跳台阶~C语言~刷题

引言 这次,我们要与一只活泼可爱的小青蛙合作,并引导它跳台阶。小青蛙的体力十分充沛,尤其喜欢跳跃,让它作为我们的助手,来看看有几种跳跃指定台阶数的方法。 本文会涉及到函数递归的知识,后续我会更新讲解…

清华系2B模型杀出,性能吊打LLaMA-13B

2 月 1 日,面壁智能与清华大学自然语言处理实验室共同开源了系列端侧语言大模型 MiniCPM,主体语言模型 MiniCPM-2B 仅有 24 亿(2.4B)的非词嵌入参数量。 在综合性榜单上与 Mistral-7B 相近,在中文、数学、代码能力表现…

基于深度卷积神经网络的图像配准(DeepSlice)

文章目录 一、基于DeepSlice的切片配准1.1、研究现状1.2、网络模型(DeepSlice)1.3、优化策略1.3.1、开发了一个基准数据集(GT)1.3.2、构建了阶段二的训练数据集(增强训练)1.3.3、角度集成 切割索引&#x…

【Linux】统信服务器操作系统V20 1060a-AMD64 Vmware安装

目录 ​编辑 一、概述 1.1 简介 1.2 产品特性 1.3 镜像下载 二、虚拟机安装 一、概述 1.1 简介 官网:统信软件 – 打造操作系统创新生态 统信服务器操作系统V20是统信操作系统(UOS)产品家族中面向服务器端运行环境的,是一款…

Linux驱动 SPI子系统

1、SPI协议 SPI(Serial Peripheral Interface)是一种同步串行数据通信协议,通常用于连接微控制器和外部设备,如传感器、存储器、显示器等。SPI协议使用四根线进行通信,包括时钟线(SCLK)、数据输…

CSS要点总结

一、CSS 快速入门 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>css 快速入门</title><!-- 解读1. 在 head 标签内&#xff0c;出现了 <style type"text/css"></style…

Redis 的持久化机制是什么?各自的优缺点?

Redis 提供两种持久化机制 RDB&#xff08;默认&#xff09; 和 AOF 机制: RDB&#xff1a;是Redis DataBase缩写快照 RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中&#xff0c;对应产生的数据文件为dump.rdb。通过配置文件中的save参数来…

ChatLaw:基于LLaMA微调的法律大模型

文章目录 动机数据组成模型框架模型评估 北大团队发布首个的中文法律大模型落地产品ChatLaw&#xff0c;为大众提供普惠法律服务。模型支持文件、语音输出&#xff0c;同时支持法律文书写作、法律建议、法律援助推荐。 github地址&#xff1a;https://github.com/PKU-YuanGroup…

备份RK35XX 设备的ubuntu根文件系统的方法

简介 我们使用 RK35XX 提供的SDK包制作了一个完整的 ubuntu 镜像,烧录到设备中,会在设备中安装很多我们需要的软件,运行的一些自己写的脚本和业务程序,当我们有很多台设备时,不可能每台都一个个去安装,此时我们就需要一个工具来备份当前设备的根文件系统,然后再放到 SD…

2023年上-未来几年我要做什么

1月份&#xff0c;离职。 2月份&#xff0c;春节休假回来&#xff0c;中旬去参加了一个月的瑜伽培训&#xff0c;学会了倒立、鹤蝉。。。。 3月份&#xff0c;瑜伽培训结束&#xff0c;开始收拾房子&#xff0c;并调研各类项目。 4月份&#xff0c;参与了朋友的区块链项目 …

Leetcode—203. 移除链表元素【简单】

2024每日刷题&#xff08;一零九&#xff09; Leetcode—203. 移除链表元素 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(n…