当前课程知识点:Linux 内核分析与应用 >  第7章 内核同步 >  7.2 内核同步机制 >  Video

返回《Linux 内核分析与应用》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《Linux 内核分析与应用》慕课在线视频列表

Video课程教案、知识点、字幕

大家好 今天我们来讲一下内核的同步措施

为了避免并发 防止竞争

内核提供了一组同步方法来提供对共享数据的保护

原子操作在前面我们已经介绍过了 下面我们介绍其他几种

首先我们来介绍下中断屏蔽

在进入临界区之前 我么可以屏蔽系统中的中断

从而保证正在执行的内核任务

不被中断处理程序所抢占 防止某些竞态条件的发生

在退出临界区域以后呢 可以重新打开中断

但是中断屏蔽是有缺点的

刚才我们介绍的那两个函数都只能禁止和开启本地CPU内的中断

并不能解决多处理器引发的竞争状态

在中断屏蔽期间所有的中断都无法得到处理

因此长时间的屏蔽中断是很危险的

有可能造成数据的丢失 甚至系统的崩溃

那么下面呢 我们来介绍下自旋锁

自旋锁是专为防止多处理器并发而引入的一种锁

它在内核中大量应用于中断处理的部分

而对于单处理器来说呢 可简单采用关中断的方式

就可以防止中断处理程序的并发执行

自旋锁最多只能被一个内核使用 比如图中

在t1时刻CPU A上的任务试图获得自旋锁

并且成功的获得进入临界区了

在t2时刻CPU B上的任务试图申请自旋锁

那么这个任务就会一直进行忙循环 也就是旋转直到t3时刻锁被释放以后呢

它才会获得而进入临界区

那么自旋锁设置的目的是什么呢 它的初衷就是在短期时间内进行轻量级的锁定

所以自旋锁不应该被长时间的持有

自旋锁在内核中主要用来防止多处理器中的并发访问临界区

防止内核抢占造成的竞争

自旋锁不允许任务的睡眠 持有自旋锁任务睡眠会造成死锁

因此自旋锁能够在中断上下文中使用

那么自旋锁如何定义和使用呢 在内核中给出了它的定义的方式

我们看首先定义了一个原始的自旋锁

以及它的类型 然后我们定义了自旋锁的类型spinlock_t

那么如何去使用自旋锁呢我们调用一个宏 先定义一个自旋锁

然后通过spin_lock 来对这个临界区加锁

接着进入临界区 那么出来的时候要解锁

关于自旋锁还有很多种的变种

内核提供了一组API 在此就不一一介绍了

下面我们来介绍信号量 Linux中的信号量是一种睡眠锁

一个任务试图获得一个已被持有的信号量的时候呢

信号量会将其推入到等待队列

然后让其睡眠 这时候处理器就获得自由而去执行其他的代码

当处理信号的进程将信号量释放以后呢

在等待队列中的一个任务就被唤醒 从而可以获得这个信号量

那么我们看到信号量是具有睡眠特性的

适用于锁被长时间持有的情况 只能在进程上下文中使用

内核中是如何定义信号量的呢

那么内核中有一个信号量的数据结构

我们看到它有三个字段 第一个字段lock是自旋锁

是防止多处理器并行造成的错误

那么第二字段count是计数器 当它大于零的时候表示可用资源数

小于零的时候其绝对值表示等待的进程数

第三个字段是wait_list就是等待资源的进程队列

下面介绍一下信号量的相关操作

也就是down操作 对应于操作系统里头呢也就是p操作

那么这个down操作呢 它的这个参数就是信号量类型

我们看到 当我们对这个count进行减一的操作的时候首先要加锁

使信号量的操作在关闭的情况下进行

防止多处理器并发操作造成的错误

若信号量可用的话 我们就将信号量的计数器减一

如果无信号量可用的时候 就要调用__down函数进入睡眠等待状态

那么当我们要出这个临界区的时候呢 就对信号量的操作进行解锁操作

那么down操作之后调用__down()函数 而__down函数调用__down_common()

那么后者呢是各种down操作的统一函数

那么信号量相关操作的第二个操作就是释放信号量的up操作

相当于操作系统里面讲的v操作

那么这个操作跟p操作是相反的 它是对这个信号量的

计数器进行加一操作 。在对这个加一操作

之前或者之后呢首先对它要进行加锁

那么出来的时候就要进行解锁

关于信号量的操作有一组函数 那么我们看到down操作有五个函数

那么在这里我们对这个函数不一一介绍 但呢每个函数呢

它有差异性 需要读者仔细地去体会它

下面给出信号量与自旋锁的比较

我们看一下 需求不同那么建议的加锁方法也不同

在低开销加锁 短期锁定的情况下建议优先使用自旋锁

对于长期加锁的情况优先使用信号量

对于中断上下文中加锁建议使用自旋锁

对持有锁时需要睡眠 调度的情况下建议使用信号量

在内核中还有其他的同步措施

比如说互斥锁 实际上互斥锁和信号量为1的情况非常的类似 可以允许睡眠

比如说还有完成变量 完成变量是什么呢 它是基于等待队列的一种机制

如果在内核中一个任务需要发出信号通知另一个任务

发生了某个特定的事件 就可以用完成变量

还有一种非常有名的机制叫RCU机制

也就是读-拷贝修改锁机制

这种机制呢许多个读者同时访问被保护的数据

又允许多个读者和多个写者同时访问被保护的数据

前面我们对同步措施做了一个概要的介绍 下面我们来介绍经典的例子

就是生产者与消费者并发的实例

那么问题的描述就是一个生产厂家 一个经销商 一个仓库

厂家生产一批产品放在仓库里 再通知经销商来批发

经销商卖完产品再向厂家下订单 生产厂家再生产下一批产品

那么对这个问题 我们看到是典型的生产者和消费者的问题

那么生产者和消费者就用内核线程来模拟

公共缓冲区就是临界区 同一个时刻呢只能有一个线程访问临界区

具体的代码大家可以参考教材

下一个例子就是内核多任务并发控制实例

假设存在这样一个内核共享资源也就是链表 另外我们构造一个内核多任务访问链表的场景

Linux线程向链表中加入新的结点 内核定时器呢定时地删除结点

系统调用呢销毁链表

上面三者内核任务在并发的执行 有可能会破坏链表的数据的完整性

所以呢我们必须对链表进行同步访问保护 以确保数据的一致性

本实例的讲解在下一讲中视频录制中具体讲解 希望大家仔细地体会和查看

最后我们说动手实践在Linux内核之旅网站第七期

内核中的调度与同步呢 为大家介绍内核中的任务调度机理和各种逻辑关系

在此基础上为大家介绍了

内核中需要同步保护的根本原因和保护措施

并提供内核共享链表同步访问的例子

帮助大家理解内核编程中的同步问题

希望大家在最新内核版本下进行调试

参考资料是《深入理解Linux内核》第三版的第五章

《Linux内核的设计与实现》第三版的第十章

蜗窝科技网站内核同步的系列文章

最后大家带着思考离开

在多核环境下中断屏蔽机制与单核有什么差异

谢谢大家

Linux 内核分析与应用课程列表:

第1章 概述

-1.1 Linux操作系统概述

--1.1 Linux 操作系统概述

-1.2 Linux内核结构以及内核模块编程

--Video

-1.3 Linux内核源码中的双链表结构

--Video

-1.4 源码分析-内核中的哈希表

--Video

-1.5 动手实践-Linux内核模块的插入和删除

--Video

-第1章 概述--章节测验

-第1章导学--引领你进入Linux内核的大门

第2章 内存寻址

-2.1 内存管理之内存寻址

--Video

-2.2 段机制

--Video

-2.3分页机制

--Video

-2.4 动手实践-把虚拟地址转换成物理地址

--Video

-第2章 内存寻址--章节测验

-第二章导学-从零打造自己的操作系统

第3章 进程管理

-3.1 进程概述

--Video

-3.2 Linux进程创建

--Video

-3.3 Linux进程调度

--Video

-3.4 动手实践-打印进程描述符task_struct中的字段

--Video

-3.5工程实践-基于内核模块的负载监控

--Video

-第3章 进程管理--章节测验

-第三章导学-进程背后琳琅满目的宝贝到哪里挖?

第4章 内存管理

-4.1 Linux内存管理机制

--Video

-4.2 进程用户空间管理机制

--Video

-4.3 物理内存分配与回收机制(上)

--Video

-4.4 物理内存分配与回收机制(下)

--Video

-4.5 动手实践-Linux内存映射基础(上)

--Video

-4.6 动手实践-Linux内存映射实现(中)

--Video

-4.7 动手实践-Linux内存映射测试(下)

--Video

-4.8 初学者对内存管理的常见疑惑

--初学者对内存管理的常见疑惑(一)

--初学者对内存管理的常见疑惑(二)

--初学者对内存管理的常见疑惑(三)

-第4章 内存管理--章节测验

第5章 中断

-5.1 中断机制概述

--Video

-5.2 中断处理机制

--Video

-5.3 中断下半部处理机制

--Video

-5.4 时钟中断机制

--Video

-5.5 动手实践-中断上半部的代码分析及应用

--Video

-5.6 动手实践-中断下半部的代码分析及应用

--Video

-第5章 中断--章节测验

第6章 系统调用

-6.1 Linux中的各种API

--Video

-6.2 系统调用机制

--Video

-6.3 动手实践-添加系统调用(系统调用日志收集系统)

--Video

-第6章 系统调用--章节测验

第7章 内核同步

-7.1 内核同步概述

--Video

-7.2 内核同步机制

--Video

-7.3 动手实践-内核多任务并发实例(上)

--Video

-7.4 动手实践-内核多任务并发实例(下)

--Video

-第7章 内核同步--章节测验

第8章 文件系统

-8.1 虚拟文件系统的引入

--Video

-8.2 虚拟文件系统的主要数据结构

--Video

-8.3 文件系统中的各种缓存

--Video

-8.4 页高速缓存机制以及读写

--Video

-8.5 动手实践-编写一个文件系统(上)

--Video

-8.6 动手实践-编写一个文件系统(中)

--Video

-8.7 动手实践-编写一个文件系统(下)

--Video

-第8章 文件系统--章节测验

第9章 设备驱动

-9.1 设备驱动概述

--Video

-9.2 I/O空间管理

--Video

-9.3 设备驱动模型

--Video

-9.4 字符设备驱动程序简介

--Video

-9.5 块设备驱动程序简介

--Video

-9.6 动手实践-编写字符设备驱动程序

--Video

-9.7工程实践-编写块设备驱动的基础(上)

--Video

-9.8 工程实践-块设备驱动程序分析(中)

--Video

-9.9 工程实践-块设备驱动程序实现(下)

--Video

-第9章 设备驱动--章节测验

致谢与说明

-致谢与说明

--Video

直播视频:从Linux内核学习到自主操作系统研发

-从Linux内核学习到自主操作系统研发

附录:实验代码、课件以及相关素材

-各章实验代码

-《Linux内核分析与应用》课件

-《Linux操作系统原理与应用》教材课堂视频

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。