linux驱动——并发控制

今天的内容回顾的是linux驱动开发中,并发控制的使用,那么问题来了,为什么我们需要进行并发控制?想要了解并发控制的话,那么我们先来认识一下什么是并发。

什么是并发呢?就是多个执行单元同时进行,但是这里要注意,我们所说的同时,只是宏观上面的同时,微观上还是有先后的顺序执行的。

说完并发,那么问题就接踵而至,同时对资源进行访问时,会产生什么情况呢?那就是传说中的竟态了,何谓竟态,就是并发执行的单元对共享资源的访问导致的竞争状态。

并发通常会发生在多CPU之间,单CPU之间进程间的并发,单CPU上进程和中断之间,还有单CPU上中断之间都会出现并发的情况。

现在,你大概知道了我们为什么要进行并发控制了,就是为了提高工作的效率。同时访问我们的共享资源的时候会出现一系列的问题,所以我们要进行相关的限制,那么并发控制有几种呢?

下面我们将对几种常见的并发控制机制进行相关的介绍:

常见的有以下几种:中断屏蔽,自旋锁,信号量,互斥锁,还有原子操作。

1.中断屏蔽

中断屏蔽不会产生进程调度,当前的进程会一直的执行,一般我们要求中断屏蔽的时间要尽可能的短,这样可以提高我们的效率,有些复杂的中断我们还将分为中断上半部和中断下半部,上半部放一些不能被打断执行的操作,下半部我们放一些可以被中断的操作,这样会使中断的利用率更高,关于中断的操作我会在之后继续的更新,这里只是简单的提一下。

如何在linux下实现中断屏蔽,我们经常使用以下几个函数来实现中断屏蔽:

//关闭中断   然后去访问共享的资源

local_irq_disable();

//使能中断

local_irq_enable();


//保存当前的CPSR值并且关闭中断    然偶访问共享资源

local_irq_save();

//恢复中断之前的状态

local_irq_restore();

2.自旋锁

自旋锁是一种满目等待的锁,使用自旋锁的时候,他会关闭抢占,此时不会有进程的调度,在多CPU使用自旋锁时,会有个全局的标志位来控制进程间的并发,使用自旋锁的时候不允许有关可以睡眠的函数使用,因为这样会很浪费我们的CPU资源,自旋锁使用的场合通常是代码量很少的场合,他会不断的在那里等待条件的满足。

如何实现自旋锁:

//定义自旋锁

spinlock_t  lock;

//初始化自旋锁

void spin_lock_init(spinlock_t  * lock);

//获得自旋锁

void spin_lock(spinlock_t *lock) ;  或者 int  spin_trylock(spinlock_t *lock);//尝试获得锁,若获得返回真,否则返回假。

//   ...   ...    执行相关的操作

//释放自旋锁

void spin_unlock(spinlock_t  *lock);


3.信号量(PV操作)

就是通常所说的PV操作,即申请资源和释放资源,他和自旋锁类似,只有得到信号量的进程,才可以访问共享资源,不同的是,当获取不到信号量时,信号量不会进行自旋的等待而是进入休眠等待状态,使用信号量时,当有些资源不能使用的时候,会引起进程的阻塞,我们需要注意的是,信号量不能使用在中断处理函数中。

如何实现信号量:

//定义信号量

struct semaphore sem;


//初始化信号量

sema_init(struct  semaphore *sem,int  value);


//获取信号量   有两种方式  先来说所第一种   如不能获取信号则进入不可中断的等待状态

void down(struct semaphore *sem);

//第二种获取信号量的方式   若不能获得信号量 进入可以被中断的等待状态      

void  down_interrupt(struct semaphore *sem);


//释放信号量   唤醒所有等待当前信号量的进程

void  up(struct semaphore *sem);

4.互斥锁

互斥锁是一种睡眠锁,他比信号量的效率更高,它的使用方法和信号量一样,唯一不同的是,信号量常用于P,V操作,当然也可以用作互斥,而互斥锁只是用来进行互斥的。

如何使用互斥锁:

//定义互斥锁

struct  mutex_lock mlock;

//初始化互斥锁

mutex_init(struct  mutex_lock * lock);


//获得互斥锁

mutex_lock(struct  mutex_lock  * lock);


//释放互斥锁

mutex_unlock(struct mutex_lock *lock);


5.原子操作

原子操作一般针对的是单个变量值的修改,使用这些方式会让变量的值修改的时候由原子特性。我们经常会在linux内核中使用,他提供了好多的函数,有些是把修改变量和判断放在一个函数中去做,另外原子操作是不能被中断的操作。

如何实现原子操作:

//定义原子变量

typedef struct {  int  counter;  } atomic_t;

atomic_t  v;


//设置原子变量的值为 i

void  atomic_set(atomic_t *v,int i);


//获得原子变量的值

#define atomic_read(v)   (*(volatile int * )&(v)->counter)


//原子变量的加和减

void  atomic_add(int  i ,atomic_t *v); //原子变量的值加 i

void  atomic_dec(int  i ,atomic_t  *v);//原子变量的值减i


//原子变量的自增与自jian

void  atomic_inc(atomic_t *v);

void  atomic_dec(atomic_t *v);


//操作并测试   函数操作后会测试原子变量的值是否为0,为0返回true ,否则返回false

int atomic_inc_and_test(atomic_t * v);

int atomic_dec_and_test(atomic_t * v);

int atomic_sub_and_test(int i ,  atomic_t * v);


//操作并返回   函数执行完直接返回的是原子变量的值

int  atomic_add_return(int i ,atomic_t  *v);

int  atomic_sub_return(int i ,atomic_t  *v);

int  atomic_inc_return(atomic_t  *v);

int  atomic_dec_return(atomic_t  *v);


好了,以上就是对linux下驱动中的并发控制的简单介绍,我们可以再闭上眼睛回忆一下都有哪些并发控制呢?

对的,回答对了,有中断屏蔽,自旋锁,信号量,互斥锁,还有原子操作。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com
Linux设备驱动中,由于多个进程或线程可能会同时访问设备,因此需要进行并发控制以确保设备的正确性和稳定性。以下是一些常用的Linux设备驱动中的并发控制方法: 1. 互斥锁(mutex):互斥锁是用于保护临界区的一种机制,当一个进程或线程进入临界区时,其他进程或线程必须等待其退出后才能进入。Linux内核提供了多种不同类型的互斥锁,如spinlock、semaphore等,开发者可以根据实际需求选择不同的锁类型。 2. 读写锁(rwlock):读写锁是一种特殊的互斥锁,它允许同时有多个读者访问共享资源,但只允许一个写者访问。读写锁可以提高并发性能,但也需要考虑读写锁的开销。 3. 自旋锁(spinlock):自旋锁是一种忙等待的锁,当一个进程或线程无法获取锁时,它会一直循环尝试获取锁,直到获取成功。自旋锁对于短时间的临界区保护非常有效,但长时间的自旋会浪费CPU资源。 4. 原子操作(atomic):原子操作是一种不可分割的操作,可以保证操作的完整性和一致性。在Linux设备驱动中,原子操作通常用于对共享变量的操作,如增减计数器等。 除了以上方法,还有一些高级的并发控制技术,如RCU、信号量(semaphore)等,它们可以根据具体的应用场景来选择使用。在开发Linux设备驱动时,需要根据实际情况选择合适的并发控制方法,并注意避免死锁和竞争条件等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值