《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
来源:互联网 发布:o2o创业项目 php 编辑:程序博客网 时间:2024/06/06 01:08
存在共享资源(共享一个文件,一块内存等等)的时候,为了防止并发访问时共享资源的数据不一致,引入了同步机制。
主要内容:
- 同步的概念
- 同步的方法-加锁
- 死锁
- 锁的粒度
1. 同步的概念
了解同步之前,先了解另外2个概念:
- 临界区 - 也称为临界段,就是访问和操作共享数据的代码段。
- 竞争条件 - 2个或2个以上线程在临界区里同时执行的时候,就构成了竞争条件。
所谓同步,其实防止在临界区中形成竞争条件。
如果临界区里是原子操作(即整个操作完成前不会被打断),那么自然就不会出竞争条件。
但在实际应用中,临界区中的代码往往不会那么简单,所以为了保持同步,引入了锁机制。
2. 同步的方法-加锁
为了给临界区加锁,保证临界区数据的同步,首先了解一下内核中哪些情况下会产生并发。
内核中造成竞争条件的原因:
竞争原因
说明
中断中断随时会发生,也就会随时打断当前执行的代码。如果中断和被打断的代码在相同的临界区,就产生了竞争条件软中断和tasklet软中断和tasklet也会随时被内核唤醒执行,也会像中断一样打断正在执行的代码内核抢占内核具有抢占性,发生抢占时,如果抢占的线程和被抢占的线程在相同的临界区,就产生了竞争条件睡眠及用户空间的同步用户进程睡眠后,调度程序会唤醒一个新的用户进程,新的用户进程和睡眠的进程可能在同一个临界区中对称多处理2个或多个处理器可以同时执行相同的代码
为了在编写内核代码时避免出现竞争条件,在编写代码之前就要考虑好临界区在哪,以及怎么加锁。
在编写完代码后再加锁是非常困难的,很可能还会导致部分代码重写。
编写内核代码时,时时记着下面这些问题:
- 这个数据是不是全局的?除了当前线程以外,其他线程能不能访问它?
- 这个数据会不会在进程上下文或者中断上下文中共享?它是不是要在两个不同的中断处理程序中共享?
- 进程在访问数据时可不可能被抢占?被调度的新程序会不会访问同一数据?
- 当前进程会不会睡眠(或者阻塞)在某些资源上,如果是,它会让共享数据处于何种状态?
- 怎样防止数据失控?
- 如果这个函数又在另一个处理器上被调度将会发生什么?
3. 死锁
死锁就是所有线程都在相互等待释放资源,导致谁也无法继续执行下去。
下面一些简单的规则可以帮助我们避免死锁:
- 如果有多个锁的话,尽量确保每个线程都是按相同的顺序加锁,按加锁相反的顺序解锁。(即加锁a->b->c,解锁c->b->a)
- 防止发生饥饿。即设置一个超时时间,防止一直等待下去。
- 不要重复请求同一个锁。
- 设计应力求简单。加锁的方案越复杂就越容易出现死锁。
4. 锁的粒度
在加锁的时候,不仅要避免死锁,还需要考虑加锁的粒度。
锁的粒度对系统的可扩展性有很大影响,在加锁的时候,要考虑一下这个锁是否会被多个线程频繁的争用。
如果锁有可能会被频繁争用,就需要将锁的粒度细化。
细化后的锁在多处理器的情况下,性能会有所提升。
举个例子说明一下:比如给一个链表加锁,同时有A,B,C 3个线程频繁访问这个链表。
那么当A,B,C 3个线程同时访问这个链表时,如果A获得了锁,那么B,C线程只能等待A释放了锁后才能访问这个链表。
如果A,B,C 3个线程访问的是这个链表的不同节点(比如A是修改节点listA,B是删除节点listB,C是追加节点listC),
并且这3个节点不是连续的,那么3个线程同时运行是不会有问题的。
这种情况下就可以细化这个锁,把加在链表上的锁去掉,改成把锁加在链表的每个节点上。(也就是锁粒度的细化)
那么,上述的情况下,A,B,C 3个线程就可以同时访问各自的节点,特别是在多处理器的情况下,性能会有显著提高。
最后还有一点需要提醒的是,锁的粒度越细,系统开销越大,程序也越复杂,所以对于争用不是很频繁的锁,就没有必要细化了。
存在共享资源(共享一个文件,一块内存等等)的时候,为了防止并发访问时共享资源的数据不一致,引入了同步机制。
主要内容:
- 同步的概念
- 同步的方法-加锁
- 死锁
- 锁的粒度
1. 同步的概念
了解同步之前,先了解另外2个概念:
- 临界区 - 也称为临界段,就是访问和操作共享数据的代码段。
- 竞争条件 - 2个或2个以上线程在临界区里同时执行的时候,就构成了竞争条件。
所谓同步,其实防止在临界区中形成竞争条件。
如果临界区里是原子操作(即整个操作完成前不会被打断),那么自然就不会出竞争条件。
但在实际应用中,临界区中的代码往往不会那么简单,所以为了保持同步,引入了锁机制。
2. 同步的方法-加锁
为了给临界区加锁,保证临界区数据的同步,首先了解一下内核中哪些情况下会产生并发。
内核中造成竞争条件的原因:
竞争原因
说明
中断中断随时会发生,也就会随时打断当前执行的代码。如果中断和被打断的代码在相同的临界区,就产生了竞争条件软中断和tasklet软中断和tasklet也会随时被内核唤醒执行,也会像中断一样打断正在执行的代码内核抢占内核具有抢占性,发生抢占时,如果抢占的线程和被抢占的线程在相同的临界区,就产生了竞争条件睡眠及用户空间的同步用户进程睡眠后,调度程序会唤醒一个新的用户进程,新的用户进程和睡眠的进程可能在同一个临界区中对称多处理2个或多个处理器可以同时执行相同的代码
为了在编写内核代码时避免出现竞争条件,在编写代码之前就要考虑好临界区在哪,以及怎么加锁。
在编写完代码后再加锁是非常困难的,很可能还会导致部分代码重写。
编写内核代码时,时时记着下面这些问题:
- 这个数据是不是全局的?除了当前线程以外,其他线程能不能访问它?
- 这个数据会不会在进程上下文或者中断上下文中共享?它是不是要在两个不同的中断处理程序中共享?
- 进程在访问数据时可不可能被抢占?被调度的新程序会不会访问同一数据?
- 当前进程会不会睡眠(或者阻塞)在某些资源上,如果是,它会让共享数据处于何种状态?
- 怎样防止数据失控?
- 如果这个函数又在另一个处理器上被调度将会发生什么?
3. 死锁
死锁就是所有线程都在相互等待释放资源,导致谁也无法继续执行下去。
下面一些简单的规则可以帮助我们避免死锁:
- 如果有多个锁的话,尽量确保每个线程都是按相同的顺序加锁,按加锁相反的顺序解锁。(即加锁a->b->c,解锁c->b->a)
- 防止发生饥饿。即设置一个超时时间,防止一直等待下去。
- 不要重复请求同一个锁。
- 设计应力求简单。加锁的方案越复杂就越容易出现死锁。
4. 锁的粒度
在加锁的时候,不仅要避免死锁,还需要考虑加锁的粒度。
锁的粒度对系统的可扩展性有很大影响,在加锁的时候,要考虑一下这个锁是否会被多个线程频繁的争用。
如果锁有可能会被频繁争用,就需要将锁的粒度细化。
细化后的锁在多处理器的情况下,性能会有所提升。
举个例子说明一下:比如给一个链表加锁,同时有A,B,C 3个线程频繁访问这个链表。
那么当A,B,C 3个线程同时访问这个链表时,如果A获得了锁,那么B,C线程只能等待A释放了锁后才能访问这个链表。
如果A,B,C 3个线程访问的是这个链表的不同节点(比如A是修改节点listA,B是删除节点listB,C是追加节点listC),
并且这3个节点不是连续的,那么3个线程同时运行是不会有问题的。
这种情况下就可以细化这个锁,把加在链表上的锁去掉,改成把锁加在链表的每个节点上。(也就是锁粒度的细化)
那么,上述的情况下,A,B,C 3个线程就可以同时访问各自的节点,特别是在多处理器的情况下,性能会有显著提高。
最后还有一点需要提醒的是,锁的粒度越细,系统开销越大,程序也越复杂,所以对于争用不是很频繁的锁,就没有必要细化了。
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- <<Linux内核设计与实现>>读书笔记(九)-内核同步介绍
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- Linux内核设计与实现读书笔记(7)-内核同步介绍
- 《linux内核设计与实现》 - 读书笔记:内核同步介绍
- Linux内核设计与实现读书笔记九——内核同步介绍(内附思维导图)
- Linux内核设计与实现 读书笔记(9)内部同步介绍
- linux内核设计与实现---内核同步介绍(9)
- 《Linux内核设计与实现》读书笔记(九)
- Linux内核设计与实现读书笔记(8)-内核同步方法
- linux内核设计与实现读书笔记——内核同步
- Linux内核设计与实现 读书笔记(10)内核同步方法
- 《Linux内核设计与实现》读书笔记- 内核同步方法
- 《Linux内核设计与实现》——内核同步介绍
- Linux内核设计与实现之内核同步介绍
- 在windows上面建立端口传文件
- ReactNative获取ListView当前界面展示的row的个数
- Android 如何对apk文件进行反编译以及重新打包签名 标签: apktoolandroid反编译jebSmali2Java 2016-05-10 16:00 3897人阅读 评论(0) 收藏
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 堆与堆排序
- 《Linux内核设计与实现》读书笔记(九)- 内核同步介绍
- JSP与JavaBean
- HDU 5171 GTY's birthday gift(矩阵快速幂模板)
- Ubuntu安装opencv
- jquery attr prop checkbox已有checked=checked但不显示勾选问题
- 计算机导论第五课之程序怎么样运行
- C语言基础编程(switch语句)
- C语言解析MNIST数据集
- 面试笔试--TCP/IP知识点