linux驱动中并发和竞争的处理

linux驱动中并发和竞争的处理


前言

    Linux 是一个多任务操作系统,肯定会存在多个任务共同操作同一段内存或者设备的情况,多个任务甚至中断都能访问的资源叫做共享资源,就和共享单车一样。在驱动开发中要注意对共享资源的保护,也就是要处理对共享资源的并发访问。比如共享单车,大家按照谁扫谁骑走的原则来共用这个单车,如果没有这个并发访问共享单车的原则存在,只怕到时候为了一辆单车要打起来了。在 Linux 驱动编写过程中对于并发控制的管理非常重要,本章我们就来学习一下如何在 Linux 驱动中处理并发。
    Linux驱动的并发处理工具共有4种,分别为 原子操作、自旋锁、信号量和互斥锁 。根据其不同的特性,它们拥有不同的用途。

一、原子操作
1.1 原子操作介绍

    首先看一下原子操作,原子操作就是指不能在进一步分割的操作,一般原子操作用于变量或者位操作。假如现在要对无符号整形变量 a 赋值,值为 3,对于 C 语言来讲很简单,直接就是:

	a = 3

    但是 C 语言要先编译为成汇编指令,ARM 架构不支持直接对寄存器进行读写操作,比如要借助寄存器 R0、R1 等来完成赋值操作。假设变量 a 的地址为 0X3000000,“a=3”这一行 C语言可能会被编译为如下所示的汇编代码:

ldr r0, =0X30000000 /* 变量 a 地址 */
ldr r1, = 5 /* 要写入的值 */
str r1, [r0] /* 将 5 写入到 a 变量中 */

    示例代码只是一个简单的举例说明,实际的结果要比示例代码复杂的多。从上述代码可以看出,C 语言里面简简单单的一句“a = 3”,编译成汇编文件以后变成了 3 句,那么程序在执行的时候肯定是按照示例代码中的汇编语句一条一条的执行。那么CPU在多个线程操作这个数的时候,当前线程就有可能被其他线程打断,从而给a赋了错误的值。

1.2 原子整形操作API函数

    Linux 内核定义了叫做 atomic_t 的结构体来完成整形数据的原子操作,在使用中用原子变量来代替整形变量,此结构体定义在 include/linux/types.h 文件中,定义如下:

typedef struct {
	int counter;
} atomic_t;

如果要使用原子操作 API 函数,首先要先定义一个 atomic_t 的变量,如下所示:

atomic_t a; // 定义 a

    也可以在定义原子变量的时候给原子变量赋初值,如下所示:

atomic_t b = ATOMIC_INIT(0); // 定义原子变量 b 并赋初值为 0

    可以通过宏 ATOMIC_INIT 向原子变量赋初值。
    原子变量有了,接下来就是对原子变量进行操作,比如读、写、增加、减少等等,Linux 内核提供了大量的原子操作 API 函数,如下所示:

ATOMIC_INIT(int i) 	定义原子变量的时候对其初始化。
int atomic_read(atomic_t *v) 	读取 v 的值,并且返回。
void atomic_set(atomic_t *v, int i) 	向 v 写入 i 值。
void atomic_add(int i, atomic_t *v) 	给 v 加上 i 值。
void atomic_sub(int i, atomic_t *v) 	从 v 减去 i 值。
void atomic_inc(atomic_t *v) 	给 v 加 1,也就是自增。
void atomic_dec(atomic_t *v) 	从 v 减 1,也就是自减
int atomic_dec_return(atomic_t *v) 	从 v 减 1,并且返回 v 的值。
int atomic_inc_return(atomic_t *v) 	给 v 加 1,并且返回 v 的值。
int atomic_sub_and_test(int i, atomic_t *v) 	从 v 减 i,如果结果为 0 就返回真,否则返回假
int atomic_dec_and_test(atomic_t *v) 	从 v 减 1,如
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值