当前位置: 首页 > news >正文

【linux】常用的互斥手段及实例简述

文章目录

  • 10. 原子变量(atomic_t)
  • 20. 自旋锁(spinlock_t)
  • 21. 读写锁(rwlock_t)
  • 22. 顺序锁(seqlock_t)

10. 原子变量(atomic_t)

  1. 头文件
#include <linux/types.h>
// -> <linuc/atomic.h>
// 		-> <asm-generic/atomic64.h>
  1. 结构体
/* 32bit */
typedef LONG atomic_t;
#define LONG        .wordk
/* 64bit */
typedef struct {long long counter;
} atomic64_t;
  1. 实例
#ifdef _TEST_ATOMIC_32/* 32bit */int val_a = 0;atomic_t a = ATOMIC_INIT(0);// int a = 32;// set / readatomic_set(&a, 32);         // a = 100;val_a = atomic_read(&a);    // VAL = a;// add / subatomic_add(1, &a);          // a = a + 1;atomic_sub(2, &a);          // a = a - 1;// inc / decatomic_inc(&a);             // a++;atomic_dec(&a);             // a--;
#else/* 64bit */u64 val_b = 0;                      // unsigned long long val_b = 0;atomic64_t b = ATOMIC64_INIT(0);    // unsigned long long b = 0;// set / readatomic64_set(&b, 64);               // b = 64val_b = atomic64_read(&b);          // VAL = b;// add / subatomic64_add(1, &b);                // b = b + 1;atomic64_sub(2, &b);                // b = b - 1;// inc / decatomic64_inc(&b);                   // b++;atomic64_dec(&b);                   // b--;
#endif
  1. 备注
    32bit与64bit有两套接口,但是部分API是通用的,
    底层实现都是靠barrier(),
    不同长度的数据读取也可以靠类型转换来实现。

20. 自旋锁(spinlock_t)

  1. 头文件
#include <linux/spinlock_types.h>         // for spinlock
  1. 结构体
typedef struct spinlock {union {struct raw_spinlock rlock;};
} spinlock_t;
  1. 实例
#include <linux/spinlock_types.h>static DEFINE_SPINLOCK(vga_lock);		// init{unsigned long flags;spin_lock_irqsave(&test_spinlock, flags);{// do something}spin_unlock_irqrestore(&test_spinlock, flags);}
#if 0{/* in irq */spin_lock();spin_unlock();}
#endif
  1. 备注
  1. 临界代码中不要调用会引起系统调度的代码,即不要把cpu让出去
  2. 中断肯定会导致嵌套,而锁又不能做系统调度,两者量结合会导致死锁,所以需要屏蔽中断。
    2.1 调用_irqsave()、_irqrestore()做中断现场的保存和恢复
    2.2 中断中直接调用,不需要处理中断
  3. 头文件会有嵌套,这里的头文件只是最终的头文件,下面不再赘述

21. 读写锁(rwlock_t)

  1. 头文件
#include <linux/rwlock_types.h>         // for rwlock
  1. 结构体
typedef struct {arch_rwlock_t raw_lock;
} rwlock_t;
  1. 实例
#include <linux/rwlock_types.h>static DEFINE_RWLOCK(test_rwlock);		// init{unsigned long flags;/* read lock */read_lock_irqsave(&test_rwlock, flags);{// read something}read_unlock_irqrestore(&test_rwlock, flags);/* write lock */write_lock_irqsave(&test_rwlock, flags);{// write something}write_unlock_irqrestore(&test_rwlock, flags);}
  1. 备注
  1. 自旋锁解决了 读-读、读-写、写-写的竞态,但是读-读是可以并发的,所以引入了读写锁
  2. 与自旋锁在使用上的区别在于,定义了将读-写分成了两部分API,由程序员分类处理读写

22. 顺序锁(seqlock_t)

  1. 头文件
#include <linuc/seqlock.h>              // for seqlock
  1. 结构体
typedef struct {struct seqcount seqcount;spinlock_t lock;
} seqlock_t;
  1. 实例
#include <linuc/seqlock.h>static DEFINE_SEQLOCK(test_seqlock);	// init{unsigned long flags;/* read seqlock */{unsigned seq;
retry:seq = read_seqbegin(&test_seqlock);{// read something}if(read_seqretry(&test_seqlock, seq))goto retry;}/* write seqlock */write_seqlock_irqsave(&test_seqlock, flags);{// write something}write_sequnlock_irqrestore(&test_seqlock, flags);}
  1. 备注
  1. 顺序锁在读写锁的基础上,又允许了写-写的并发,其实现逻辑如下:
    1.1 写:获取锁,写操作,释放锁(写操作会修改序号,给读取函数来判断)
    1.2 读:先获取一个序号,读操作,判断之前的序号是否变化,如果变化了重新执行“获取-读取-判断”
http://www.lryc.cn/news/135724.html

相关文章:

  • STM32 F103C8T6学习笔记12:红外遥控—红外解码-位带操作
  • linux 环境收集core文件步骤
  • Git企业开发控制理论和实操-从入门到深入(一)|为什么需要Git|Git的安装
  • 上篇——税收大数据应用研究
  • 疲劳驾驶检测和识别4:C++实现疲劳驾驶检测和识别(含源码,可实时检测)
  • Android WakefulBroadcastReceiver的使用
  • python知识:什么是字符编码?
  • Vue2中使用Pinia
  • Docker关于下载,镜像配置,容器启动,停止,查看等基础操作
  • 穿越网络迷雾的神奇通道 - WebSocket详解
  • 无脑入门pytorch系列(五)—— nn.Dropout
  • Python土力学与基础工程计算.PDF-压水试验
  • Linux入门
  • 适合国内用户的五款ChatGPT插件
  • Dubbo Spring Boot Starter 开发微服务应用
  • linux中互斥锁,自旋锁,条件变量,信号量,与freeRTOS中的消息队列,信号量,互斥量,事件的区别
  • 安装docker服务,配置镜像加速器
  • CF 896 C Willem, Chtholly and Seniorious(珂朵莉树模板)
  • Android Jetpack组件的全方位分析
  • Prometheus+Grafana+AlertManager监控SpringBoot项目并发送邮件告警通知
  • 猿辅导Motiff亮相IXDC 2023国际体验设计大会,发布新功能获行业高度关注
  • 【QT】重写QAbstractLIstModel,使用ListView来显示多列数据
  • 【从零学习python 】64. Python正则表达式中re.compile方法的使用详解
  • 【FAQ】视频云存储/安防监控EasyCVR视频汇聚平台如何通过角色权限自行分配功能模块?
  • 基于Spring Boot的社区诊所就医管理系统的设计与实现(Java+spring boot+MySQL)
  • mysql从传统模式切到GTID模式后启动主从,主从异常报错1236
  • Qt+C++串口调试接收发送数据曲线图
  • 【从零学习python 】75. TCP协议:可靠的面向连接的传输层通信协议
  • IPv4 基础概念
  • stm32片内读写项目总结(多字节读写tongxindu)