内核同步方法总结

深度解析Linux读写锁逻辑 Reader偷锁的场景主要发生在唤醒top waiter的过程中,这时候临界区没有线程,被唤醒的reader或者writer也没有持锁(writer需要被调度到CPU上执行之后才会试图持锁,高负载的场景下,锁被偷的概率比较大,reader是唤醒后立刻持锁,被偷的几率小一点)。在当前线程进入阻塞之前,我们需要进行试图持锁的动作(上面是空队列场景检查,这里的逻辑稍微复杂一点,由于已经入队,这里需要调用rwsem_mark_wake函数来完成阻塞后唤醒的动作),毕竟这时候可能恰好owner离开临界区,变成空锁。 阅读详情
Linux中内核同步方法总结如下:
1、原子整数操作:
 原子操作可以保证指令以原子的方式运行--执行过程不能被打断.原子操作把读取和改变变量的行为包含在一个单步中执行,从而避免了竞争.

       定义:atomix_t t;

       Atomic_t u = ATOMIC_INIT(0);

  操作函数定义在中,原子操作是内联函数.通过内嵌汇编指令来实现.
  Int atomic_read(atomic_t v)
  Void atomic_set(atomic_t *v,int i)
  Void atomic_add(int i,atomic_t *v)
  Void atomic_sub(int i,atomic_t *v);
  
  Void atomic_inc(atomic_t *v);
  Void atomic_dec(atomic_t *v);
  原子加减1

  Int atomic_sub_and_test(int i,atomic_t *v)
  原子地从v减i,如果等于0,返回真,否则返回假.

  Int atomic_add_negative(int i,atomic_t *v)
  结果为负数返回真,否则返回假.
  
  Int atomic_dec_and_test(atomic_t *v)
  Int atomic_inc_and_test(atomic_t *v);

  结果等于0 返回真,否则返回假.


2、原子位的操作
  定义在 这些函数对某个普通的内存地址.
  可用的位操作:
  Void set_bit(nr,voie *addr);
  设置addr指向的数据项的nr位.
  
  Void clear_bit(nr,void *addr)
  清除addr指向的数据项的第nr位.

  Test_bit(nr,void *addr)
  返回当前的指定位.
  Int test_and_set_bit(nr,void *addr);
  设置nr位的同时返回原来的值

3、spinlock自旋锁
  自旋锁最多只能被一个可执行的线程持有,等待锁的进程采用忙循环等待.
  定义在 and  自旋锁可以在中断程序中使用.在这种情况下,其他代码要获得锁必须首先关闭中断.在配置内核时,可以选定CONFIG_DEBUG_SPINLOCK选项,打开spinlock的调试功能.
   1.spinlock的初始化
   静态:spinlock_t my_lock=SPIN_LOCK_UNSIGNED ;
   动态:void spin_lock_init(spinlock_t *lock);
  2.加锁函数
   Void spin_lock(spinlock_t *lock);
   Void spin_lock_irqsave(spinlock_t *lock,unsigned long flags);
   Void spin_lock_irq(spinlock_t *lock);
   Void spin_lock_bh(spinlock_t *lock);
   如果我们的一个自旋锁能够在中断处理程序中使用,或者在中断的下半部获得,则必 须使用禁止中断的spin_lock 形式.
  3.解锁函数
   Void spin_unlock(spinlock_t *lock);
   Void spin_unlock_irqsave(spinlock_t *lock,unsingned long flags);
   Void spin_unlock_irq(spinlock_t *lock);
   Void spin_unlock_bh(spinlock_t *lock);
  4.非阻塞的自旋锁
   Int spin_trylock(spinlock_t *lock);
   Int spin_trylock_bh(spinlock_t *lock);
   成功返回0.否则返回负.
4、读取者/写入者自旋锁
  1.初始化
   静态
   Rwlock_t my_rwlock = RW_LOCK_UNLOCKED
   动态
   Rwlock_t my_rwlock;
   Rwlock_init (&my_rwlock);
  2.加锁
   Read/write_lock();
   Read/wrte_lock_irq();
   Read/write_lock_irqsave();
   Read/write_lock_bh();
  3.解锁
   Read/write_unlock();
   Read/write_unlock_irq();
   Read/write_unlock_irqsave();
   Read/write_unlock_bh();
  4.其他   write_trylock();
   Rw_is_locked();
   注意:读/写锁机制要更照顾读者.当读者持有时,写者必须等待.如果有大量的读者,必定会引起写者处于饥饿状态.所以如果加锁时间不长,并且代码不会睡眠,可以利用自旋锁.如果加锁时间很长,或者代码在持有锁时可能睡眠,则最好使用信号量来枷锁.
5、信号量和互斥体
  信号量的特征:
   1.信号量适用于锁会被长期持有时,因为开销比较大.
   2.只有在进程的上下文才能获得信号量,因为获取信号量时可能导致睡眠,不适用中 断上下文.
   3.可以在持有信号量时去睡眠,因此可以在持有信号量的时候和用户空间同步.
   4.不能在持有信号量的同时持有自旋锁.
   5.信号量可以允许任意数量的持有者,而自旋锁在一个时刻只能有一个持有者.
   6.只拥有一个持有者的信号量称为互斥信号量
6、信号量的实现
  1.申明
   静态
   Static DECLARE_SEMAPHORE_GENERIC(name,count);
   或申明一个互斥信号量
   Static DECLARE_MUTEX(name);
   动态
   Struct semaphore sem;
   Sema_init(sem.count);
   Int_MUTEX(sem);
   Int_MUTEX_LOCKED(sem);
  2.获取信号量
   Void down(struct semaphore *sem)
   减小信号量的值.返回获得的信号量
   
   Int down_interruptible(struct semaphore *sem)
   在等待信号量时,可以被用户空间程序通过信号中断.如果操作被中断,则返回非零  值,调用者无法获得信号量.注意:调用时始终要检查返回值.
   Int down_trylock(struct semaphore *sem);
   不会休眠,如果不能获得信号量,立即返回一个非零值.
  3.释放信号量
   Viod up(struct semaphore *sem);
7、Array.completion 机制

  1.创建
   静态
   DECLARE_COMPLETION(my_completion);
   
   动态
   Struct completion my_completion;
   Init_completion(&my_completion);
  2.等待completion
   Void wait_for_completion(struct completion *c);
   执行一个非中断的等待,用户空间无法通过signal来中断这个进程.
  3.完成completion
   Void completion(struct completiong *)
  发信号唤醒任何等待任务.
8、如何禁内核抢占.
  1.preempt_disable()
   增加抢占记数值,从而禁止内核抢占.记数为0时,可以抢占.
  2.preempt_enable()
   减少抢占记数,并当该值降为0时检查和执行被挂起的需调度的任务.
  3.preempt_enable_no_resched();
   激活内核抢占,但不检查被挂起的需调度的任务
  4.preempt_count()
   返回抢占数.

Linux内核同步机制的自旋锁原理 本文主要介绍了linux内核自旋锁是如何工作的。 立即下载

相关推荐

vivado 编译ADI AD9361 TCL脚本生成hdl工程

(4)输入"source ../../scripts/adi_make.tcl"命令(仅双引号内部命令,不包含双引号),个人理解:该命令用来加载当前所需要编译工程所需要各功能模块的信息,因为每个工程需要不同的功能模块,比如有的需要gpio模块,有的不需要gpio模块,这些模块上前面路径的library也同样以TCL脚本形式存在,当有需要时才进行编译,怎么知道当前工程需要什么模块呢就是通过"source ../../scripts/adi_make.tcl"(仅双引号内部命令,不包含双引号)命令实现。

weixin_40586423的博客 808

Linux内核同步介绍及方法

网易云课堂学习把write系统调用加入到MenuOS里面我在试验过程中在MenuOS里加入了time、time-asm、write和write-asm命令。以time和time-asm为例, 步骤如下 更新menu代码到最新版 在main函数中增加MenuConfig 增加对应的Time函数和TimeAsm函数 make rootfs 实验结果如图所示 然后使用g

miao_9的博客 3019

华为交换机与思科/华三设备LACP对接实战:手把手教你配置链路聚合

本文详细解析了华为交换机与思科、华三设备间的LACP链路聚合配置实战,涵盖核心原理、配置步骤及排错技巧。通过对比不同厂商的实现差异,提供可落地的跨厂商对接方案,助力企业网络工程师高效部署高可靠性链路聚合。

weixin_30836759的博客 423

Linux内核中的各种锁

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

luke_lx的博客 3990

RT-DETR改进策略【损失函数篇】| 通过辅助边界框计算IoU提升检测效果(Inner_GIoU、Inner_DIoU、Inner_CIoU、Inner_EIoU、Inner_SIoU)

为了弥补现有 IoU 损失在不同检测任务中泛化性弱和收敛速度慢的问题,·Inner-IoU·通过引入比例因子 “ratio” 来控制辅助边界框的尺度大小,利用不同尺度的辅助边界框来计算损失,从而加速边界框回归过程。

Limiiiing的博客 1965

深度学习时间序列预测:GRU算法构建多变量时间序列预测模型+代码实战

深度学习多变量时间序列预测:GRU算法构建多变量时间序列预测模型+代码实战 注意参考:深度学习多变量时间序列预测:GRU算法构建单变量时间序列预测模型+代码实战 GRU(Gate Recurrent Unit)是循环神经网络(Recurrent Neural Network, RNN)的一种。和LSTM(Long-Short Term Memory)一样,也是为了解决长期记忆和反向传播中的梯度等问题而提出来的。 GRU和LSTM在很多情况下实际表现上相差无几,那么为什么我们要使用新人GRU(.

data+scenario+science+insight 4033

内核同步方法

1.原子操作 原子整数操作 描述 ATOMIC_INIT(int i)   在声明一个atomic_t变量时,将它初始化为i int atomic_read(atomic_t *v)   原子地读取整数变量v void atomic_set(atomic_t *v, int i)  

theone 406

华为OD机试2025C卷 - 精准核酸检测 (C++ & Python & JAVA & JS & GO)

华为OD机试2025C卷 精准核酸检测,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1708

linux内核之内核同步

当处理多处理器之间或硬件设备之间的同步问题时,有时需要在程序中以指定的顺序发出读内存和写内存的指令(指令的指令要按照特定的顺序)。但是为了提高效率,编译器或处理器可能会对程序指令重新排序(例如,处理器在执行指令期间,会在取指令和分派时,把表面上看上去无关的指令按照自认为最好的方式排序)。在读取数据前后,序列值都会被读取,如果读取的序列值相同,则说明读操作过程中没有新的数据写入。如果在中断处理程序中使用了自旋锁,那么,在其他地方获取锁之前(例如,可以被中断的进程上下文中),需要先禁止本地中断。

抱猫人的博客 844

乐企增值税及附加税费(一般纳税人适用)申报表填报能力说明文档V3.009

申报表填报,是指企业在自有业务系统中将算税结果数据按预填规则要求加工汇总后,进行申报表填报的过程。申报表填报前对纳税申报所需的前提条件进行校验。校验通过后,应用前序算税结果数据及预填规则进行纳税申报表预填,生成申报表数据。申报表数据通过申报业务规则校验后,经纳税人确认即完成申报表填报业务。

记录点滴 345

路由三大分类:直连路由、静态路由、动态路由

直连路由、静态路由和动态路由各有其独特的特点和适用场景。直连路由适用于简单的直接连接网络,静态路由提供了精确的路径控制,而动态路由则在大型复杂网络中展现出强大的适应性和自动化能力。了解和掌握这三种路由类型的配置和管理,对于网络管理员来说,是确保网络高效、安全运行的重要技能。

网络技术联盟站 4698

内核同步的方法

在linux内核同步的介绍 一节我们介绍了同步的概念和那些数据和资源一般是需要防止并发的执行,同时就是需要同步的方法。 下面我们就介绍一下内核同步的方法:          同步就是避免并发和防止竞争条件。有关临界区的例子我就不举了,随便一本操作系统的书上都有。锁机制的提出也算解决了一些问题,我们待会再说,现在只要知道锁的使用是自愿的,非强制的。linux自身也提供了几种不同的锁机制,区别主

工匠 827

产品路线图的三种模型(RICE/MoSCoW/Kano),教你如何对需求进行优先级排序

RICE/MoSCoW/Kano三种模型,教你如何对需求进行优先级排序。 也许你会让业务提供一份ROI,记得前不久参加过一场立项会评审,一位很有意思的小产品在会上讲不清楚ROI,评审们要求会后重新梳理,小产品表达不要为难业务方干一些他们不擅长的事了。这个看似笑话的经历,背后隐藏着价值判断已经流于形式。 也许你会要求业务方直接给出需求优先级列表,把任务分为P0到P5,这样的划分除了按需求本质的优先级还同时考虑了开发资源、开发难度等问题。毫不夸张地说,我曾经拿到一张全是P0级别的需求清单,如果一切任务都是高

wenyusuran的专栏 5542

Linux内核同步方法

原子操作 自旋锁、读-写自旋锁 信号量:二值信号量、读-写信号量 互斥量 完成变量

瓦釜苑 673

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Linux内核设计与实现 - 第10章 内核同步方法

【代码】Linux内核设计与实现 - 第10章 内核同步方法。

baron-周贺贺-代码改变世界ctw 584

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

linux内核同步方法

内核中提供了多种方法来防止竞争条件,理解了这些方法的使用场景有助于我们在编写内核代码时选用合适的同步方法, 从而即可保证代码中临界区的安全,同时也让性能的损失降到最低。 主要内容: 原子操作自旋锁读写自旋锁信号量读写信号量互斥体完成变量大内核锁顺序锁禁止抢占顺序和屏障总结   1. 原子操作 原子操作是由编译器来保证的,保证一个线程对数据的操作不会被其他线程打断

everysmile的专栏 923

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

linux 内核同步方法,学习笔记之Linux内核同步方法

一、程序并发执行的原因在用户空间:调度程序完全可能选择另一个高优先级的进程到处理器上执行,所以就有可能一个程序正处于临界区时被非自愿的抢占了,如果新调度的的进程随后也进入到同一个临界区,前后两个进程之间就会产生竞争。信号是异步发生的也有可能产生竞争条件。在内核空间:中断:中断几乎可以在任何时候异步发生,也就可能随时打断当前正在执行的代码。软中断和tasklet:内核能在任何时候唤醒或调度软中断和t...

weixin_34278722的博客 204

[linux]内核同步的方法

内核同步介绍 概念: 内核同步重要的原因:linux支持多处理器,2.6引入了抢占式内核 临界区:指访问和操作共享数据的代码段 竞争条件:如果两个线程有可能处于同一临界区中同时运行 内核同步的方法: 1,原子变量 2,加锁 造成并发的原因: 1,linux支持多处理器 2,2.6引入了内核抢占 3,中断 4,内核线程睡眠使得调度程序调度另外一个进程 确定哪些数据不需要被访

知了112的专栏 1705

Linux内核同步,进程,线程同步各种方法

Linux内核同步,进程,线程同步各种方法包括我自己在内,很多人对内核,进程,线程同步都不是很清楚,下面稍微总结一下:内核同步:主要是防止多核处理器同时访问修改某段代码,或者在对设备驱动程序进行临界区保护。主要有一下几种方式:1. Mutex(互斥)头文件:#include 初始化方法:DEFINE_MUTEX(name);或者void mutex_init(struct mutex *lock);使用方法:void mutex_lock (struct mutex *lock);Tries to lock

cainiao413的专栏 936

linux内核同步技术,Linux内核同步方法

临界区和竞争条件访问和操作共享数据的代码段称为临界区。如果两个执行线程在同一个临界区中同时执行,称为竞争条件。避免并发和防止竞态出现的机制被称为同步。内核中造成并发的原因包括:中断 —— 中断几乎可以在任何时刻异步发生,也就可能随时打断当前正在执行的代码。(中断服务程序访问被打断进程正在访问的资源)软中断和tasklet —— 内核能在任何时刻唤醒或调度软中断和tasklet,打断当前正在执行的代...

weixin_42412324的博客 216

第10章内核同步方法

Linux内核提供了一组相当完备的同步方法,这些方法使得内核开发者能编写出高效而又自由竞争的代码。 10.1 原子操作 原子操作可以保证指令以原子的方式执行——执行过程不被打断。原子原本指的是不可分割的微粒,所以原子操作也就是不能被分割的指令。 两个原子操作绝对不可能并发地访问同一个变量,这样加操作就绝不会引起竞争。 内核提供两组原子操作接口——一组针对整数进行操作,另一组针对单独的位进行...

xiezhi123456的博客 346

Linux内核同步介绍和方法

Linux设备驱动中必须解决的一个问题是多个进程对共享资源的并发访问,并发访问会导致竞态,linux提供了多种解决竞态问题的方式,这些方式适合不同的应用场景。  Linux内核是多进程、多线程的操作系统,它提供了相当完整的内核同步方法。内核同步方法列表如下:中断屏蔽原子操作自旋锁读写自旋锁顺序锁信号量读写信号量BKL(大内核锁)Seq锁一、并发与竞态

wswifth的专栏 1018
上一篇: 中断处理的工作队列机制
下一篇: gdb使用及原理
kernel_learner
博客等级 码龄15年 60粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值