linux-内核锁

Linux内核基础 - mutex_lock 函数的详解 kernel 同步互斥 mutex 中断 阅读详情

目录:

一、铺垫知识

1、指令执行流

2、上下文

3、抢占

二、内核锁基础知识

1、为什么要用锁?why

2、锁保护什么?what

3、锁是如何保护资源的?How

三、各类锁的介绍

1、原子操作

2spinlock

3mutex

4

进程指令执行流

代码在CPU上执行的指令数据流,由一系列代码组成。可分为两大类:线程维度和中断维度

1cpu只要上电,就需要不停的执行指令,永不停歇,若无事可做,那就执行空指令,直到下电。cpu类似一个跑道,各个task轮流到跑道上跑。

2、用户态视角:cpu执行一个个进程或者线程,一个线程就是一个执行流。内核态视角:CPU调度执行一个个task(对应一个进程或者线程),一个task就是一个执行流CPU就这样永不疲倦的轮换执行各个task(调度)。8CPU,同一时刻,最多有8个执行流。

3并发:用户态系统调用的代码编译成so,当so被多个bin链接时,运行时,就可能有多个指令执行流,就有可能分别在cpu0cpu1上执行。宏观并行,微观串行。

4、代码是静态的,执行流是动态的,这是两个不同的视角。若只存在一个cpu,那就只有一个执行流,那就不存在微观上的并发,也就不需要锁。但我们往往使用多个cpu,因而有多个执行流,同一个代码可能在两个执行流上执行。如上图。

上下文(context)

分类:进程上下文,中断上下文(硬中断上下文、软中断上下文,不可屏蔽中断上下文)

中断能够打断进程的执行流,无论进程优先级多高,都会被打断。因此原本执行流被打断,CPU转而执行中断的指令流。因此,与上下文对应,执行流也可分为:进程执行流和中断执行流

1cpu在用户态运行时,外部中断触发,程序会先陷入内核态,保存上下文后,再执行中断代码。

2cpu在内核态运行时,外部中断触发,保存上下文后,执行中断代码。

3、中断处理函数(中断上半部)必须要快速执行完成,以便返回继续执行各个进程。中断返回时,会发生调度,原来被打断的进程未必能够得到执行。

 假设进程和中断都调用如下函数,那么就有可能出现如下场景:

进程执行流:

1、某进程执行完743行后,全局变量enable=1

2、外部触发中断。

程序执行流:

7、从744行继续执行,此时enable变成0了。后边就会出错

中断执行流:

3、中断处理函数恰好也调用这个函数;

4、走了case1的分支,将enable又改成0

5、中断执行完毕返回。

抢占

什么是抢占? 一张图展现

1、抢占可以分为用户态抢占和内核态抢占。抢占时机?(中断、返回用户态、主动schedule())

2Linux kernel是抢占式内核。

 为什么要使用锁?-Why

为了性能,引入了多核。

但多核导致了并发,并发就导致了争抢,为了保证争抢有序,就出现了锁。

备注:

网上关于锁的介绍的文档很多,推荐知乎兰新宇的博客

术道经纬 - 知乎

关于锁的介绍,有一系列文章,个人感觉写的非常不错,我主要从这个博客学习锁的知识。

锁保护什么?-What

锁保护的对象:公共资源。公共资源,从某一方面讲,就是全局变量,或者从堆里面申请的共用内存。

如右图内核代码:

1、锁保护的是全局变量zone(从堆上申请的)。

2、无法保护局部变量tmplow,局部变量也不需要保护,想想这是为什么?

3、代码段不需要保护,因为它是只读的。

误区:常认为锁保护的是一段代码和变量。

其实:从保护资源的角度,锁只是为了保护全局变量,公共资源是一种更严谨的通用的说法。若非要说“锁也保护了代码”,那也只是在保护全局变量的时候,顺便保护了代码而已。

使用锁,首先要搞清楚使用锁的目的是什么?要保护什么?

锁是如何保护资源的?--How

核心原理:根据全局变量的状态来实现锁的控制。

“统一到门口排队,依次获得钥匙”

无进程持锁时,lock=0

进程0持锁后,lock=1

进程1再尝试持锁时,由于lock=1,无法获取,只能等待。

因此:lock一定要是全局的8字节,其实只用1bit即可Spinlock就充分利用这8个字节,仅用1bit表示锁状态。

衍生出锁的两大功能:同步和保护。

锁的种类

锁的分类

相关API

特点

注意点

原子操作:atomic

atomic_read(atomic_t * v);

atomic_se

Linux内核中mutex,spinlock的使用 并发性的,在CPU1线程B获取锁B,同时想获取锁A,导致AB-BA死锁。锁的粒度:在大项目中,使用太少的锁是个问题。锁A发生在中断上下文中:如果中断发生,中断处理函数尝试获取锁A,导致死锁。因此,在中断上下文中获取的锁必须始终在禁用中断的情况下使用。mutex lock 是睡眠锁,在等待锁时将睡眠,再锁被释放后,内核唤醒等待的进程运行;此外,不可中断状态的睡眠更多一些,必须无限期阻塞等待,任务不能打断阻塞的等待。在人机交互应用程序中,一般的经验,通常应该将进程置于可中断的睡眠状态。 阅读详情

相关推荐

kdump+crash 解决休眠锁(mutex)死锁问题

环境:arm64,Linux version 5.10.66。

paul1994的博客 1143

互斥锁(mutex lock)

互斥锁与自旋锁的关系, 以及需要注意的事项

weixin_45575944的博客 5906

linux中大内核锁(BKL--Big Kernel Lock)和自旋锁(FIFO Ticket Spinlock) -- 2014百度面试题目

这里先写一篇基础文章引入一下自旋锁、排队自旋锁和大内核锁。        自旋锁(Spinlock)是一种 Linux 内核中广泛运用的底层同步机制。自旋锁是一种工作于多处理器环境的特殊的锁,在单处理环境中自旋锁的操作被替换为空操作。当某个处理器上的内核执行线程申请自旋锁时,如果锁可用,则获得锁,然后执行临界区操作,最后释放锁;如果锁已被占用,线程并不会转入睡眠状态,而是忙等待该锁,一旦

Atlas2013的专栏 4125

浅谈Mutex (Lock)

Mutex(又叫 Lock),在多线程中,作为同步的基本类型,用来保证没有两个线程或进程同时在他们的关键区域.因为 Mutex 这种排它性,很多人认为 Mutex 开销很大,尽量避免使用它.就如这篇分析完共享数据问题后,进一步分析说明Avoiding locks来解决这个问题.但 Mutex 真的开销如此大,还是被大家误解了?Matthew Dillon写道,”Most people have the misconception that locks are slow.”, Jeff Preshing...

木牛的博客 2万+

linux内核锁机制

linux内核锁机制1.介绍1.原子操作 1.介绍 在现代操作系统里,同一时间可能有多个内核执行流在执行,因此内核其实象多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问。尤其是在多处理器系统上,更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问。在主流的Linux内核中包含了几乎所有现代的操作系统具有的同步机制,这些同步机制包括:原子操作、信号量(semapho...

陆拾贰的博客 477

linux的大内核锁与顺序锁

顺序锁包含一个顺序计数器和一个锁。但随着内核的发展和多核处理器的普及,大内核锁的粒度较粗,会导致严重的性能瓶颈,因为它会限制多个处理器同时访问内核资源。只有获取了锁的进程才能执行临界区的代码,完成对内核资源的访问,访问结束后释放锁,以便其他进程可以获取锁并访问相应资源。在一些特定的情况下,如内核初始化阶段,或者对一些全局的、不适合使用更细粒度锁的资源进行访问时,仍然会使用大内核锁。适合于写操作相对较少、读操作频繁的场景,如内核中的一些数据结构,像网络设备的统计信息等,频繁被读取但偶尔才会被更新。

最后一个bug的博客 721

大话Linux内核中锁机制之RCU、大内核锁

大话Linux内核中锁机制之RCU、大内核锁 在上篇博文中笔者分析了关于完成量和互斥量的使用以及一些经典的问题,下面笔者将在本篇博文中重点分析有关RCU机制的相关内容以及介绍目前已被淘汰出内核的大内核锁(BKL)。文章的最后对《大话Linux内核中锁机制》系列博文进行了总结,并提出关于目前Linux内核中提供的锁机制的一些基本使用观点。 十、RCU机制 本节将讨论另一种重要锁机制

xiaohaozi7107的专栏 2108

Linux锁】Linux内核锁机制

本文章主要简介Linux内核中涉及的锁机制。

day day up 506

Linux内核锁的应用

一、锁的基本知识 1、锁是通过原子操作实现的,它本身不会导致竞态。 2、为什么要使用锁? 答:因为进程同步的存在,所以要使用锁。 用户空间: (1)用户程序会被调度器抢占和重新调度,用户程序可以在任何时刻被抢占,调度器会选择一个高优先级的进程到处理器上执行。 (2)SMP的存在使得多个处理器同时执行代码。 内核空间: 中断:中断处理程序可能随时打断当前正在执行的代码。 软中断和tasklet:内核...

静虚待令,有物混成 864

linux内核锁原理

原文:http://blog.csdn.net/chenyu105/article/details/7726492     大内核锁(BKL)的设计是在kernel hacker们对多处理器的同步还没有十足把握时,引入的大粒度锁。他的设计思想是,一旦某个内核路径获取了这把锁,那么其他所有的内核路径都不能再获取到这把锁。自旋锁加锁的对象一般是一个全局变量,大内核锁加锁的对象是一段代码,里面

继续微笑lsj 1627

linux中大内核锁、互斥锁、信号量、完成变量、自旋锁区别

通过合理选择锁类型,可以提升系统性能,降低同步复杂度。

渗透测试 882

Linux内核同步】大内核锁

因此开发者们不停的缩小大内核锁的管制范围,他们首先把管住内核态入口的大内核锁去掉,但这样还不够,因为这样虽然能让多个处理器上的程序进入内核态,但有些资源上的使用还是非常麻烦,比如说 A 和 B 是两个完全不相关的资源,而且他们都被大内核锁锁住,那么只要有个进程因使用 A 资源而得到大内核锁,其他处理器上的进程就无法同时得到 B 资源(因为使用 B 资源也需要获得大内核锁,而大内核锁已经被使用 A 资源的进程率先获得了),所以他们还把这些资源一一的挑出来单独保护,这样大内核锁就只需要保护少量关键资源即可。

m0_74282605的博客 179

Linux内核中的大内核锁原理及编程实现

然而,由于BKL存在性能和可扩展性的问题,现代的Linux内核已经采用了更加灵活和细粒度的锁机制来替代BKL。在Linux内核中,大内核锁(Big Kernel Lock,简称BKL)是一种同步机制,用于保护整个内核的关键数据结构和代码段,以确保内核的正确执行。需要注意的是,BKL仅用于早期版本的Linux内核,现代的Linux内核已经逐步移除了BKL,并引入了更加细粒度的锁机制。BKL是一种全局性的锁,它的工作原理是在内核中引入一个大内核锁变量,并通过对该变量的获取和释放来实现对内核的串行化访问。

TechBurst的博客 196

Linux内核锁机制主流程总览

几乎所有锁类型都遵循这个主流程,但,决定了不同锁的适用场景和性能表现。

IT技术学习与工作笔记分享 6830

Linux内核锁实现原理,linux内核锁原理

内核锁(BKL)的设计是在kernel hacker们对多处理器的同步还没有十足把握时,引入的大粒度锁。他的设计思想是,一旦某个内核路径获取了这把锁,那么其他所有的内核路径都不能再获取到这把锁。自旋锁加锁的对象一般是一个全局变量,大内核锁加锁的对象是一段代码,里面可能包含多个全局变量。那么他带来的问题是,虽然A只需要互斥访问全局变量a,但附带锁了全局变量b,从而导致B不能访问b了。大内核锁最先的...

weixin_34324082的博客 288

Linux 中主要有哪几种内核锁?

Linux 中主要有哪几种内核锁? Linux 的同步机制从 2.0 到 2.6 以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随 Linux 从单处理器到对称多处理器的过渡; 伴随着从非抢占内核到抢占内核的过度。Linux 的锁机制越来越有效,也越来越复杂。Linux内核锁主要是自旋锁和信号量。 自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图请求一个已被争用(已经被持有)的自旋锁,那么这个线程就会一直进行忙循环——旋转——等待锁重新可用。要

m0_51538362的博客 727

【深入理解Linux锁机制】一、内核锁的由来

本系列文章,深入讲解了Linux锁机制,包括: 【深入理解Linux锁机制】一、内核锁的由来 【深入理解Linux锁机制】二、中断屏蔽 【深入理解Linux锁机制】三、原子操作 【深入理解Linux锁机制】四、自旋锁 【深入理解Linux锁机制】五、衍生自旋锁 【深入理解Linux锁机制】六、信号量 【深入理解Linux锁机制】七、互斥体 【深入理解Linux锁机制】八、完成量 旨在帮助大家更加深入的了解Linux内核相关知识。

Donge's Blog 2683
上一篇: Android系统的稳定性分析-2.0
下一篇: gdb调试-总结
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值