linux 并发与竞争

本文介绍了Linux系统中处理并发与竞争的几种机制,包括原子操作、自旋锁和信号量。原子操作适用于简单的变量保护,自旋锁适用于轻量级加锁,但可能导致资源浪费。信号量则允许线程在无法获取资源时进入休眠状态,提高处理器效率。在使用这些机制时,需要注意避免死锁和中断处理的问题,以及选择适合的同步原语以确保系统稳定性和性能。
摘要由CSDN通过智能技术生成

**

并发与竞争

**

一.简介
linux系统是一个多任务的操作系统,存在多个任务同时访问同一片内存区域,这些任务可能会相互影响覆盖内存中的数据,造成内存数据混乱。这个问题会导致系统panic。但总结一下有以下几个原因:
a. 多线程并发访问
b.内核抢占试访问
c.中断程序并发访问
d.smp多核间并发访问
并发访问带来的问题就是竞争。如果多个线程同时操作临界区的公共资源,线程之间就存在竞争关系,为了防止出现以上问题,我们在编写去佛那个的时候要考虑到并发与竞争。

二.作用
保护共享资源,防止并发访问。比如一个驱动设备的结构体,也比如环形缓冲。保护的一般是全局变量,设备结构体。

三:方式
1. 原子操作
是一种不能在分割、拆分的一种操作,一般用来作用与变量,或者位操作。比如a=3,经过编译成汇编后,如下;
LDR R0,=0x30
LDR R1, = 3
STR R1.[R0]
如果在加一个线程,也像a中写入10,在执行时,可能会出现汇编交叉,和我们理想流程不一致。
1->原子整形API函数

atomic_t a=ATOMIC_INIT(0);//定义原子变量a,并初始化为0

atomic_set(&a,10);//设置a=10;
atomic_read(&a);//读取a的值;
atomic_inc(&a);//a+1;a=11;

		2->原子位操作
		不同与atomic_t,没有数据结构体,只能直接对内存操作。

2.自旋锁
原子锁只能作用于变量或者bit保护,对于复杂的临界区,比如设备结构体变量,原子操作就不能胜任了。
当一个线程要访问某个资源,首先要获取对应的锁,锁只能被一个线程持有,只要此线程不释放持有的锁,那么其他线程就不能获取此锁。对于自旋锁,如果被A持有,线程B就会处于循环–旋转–等待状态,B线程不会进入休眠状态(或者)说做其他处理,就一直转圈。
缺点:从上来看,B线程会一直处于自选状态,这样会浪费时间,降低系统的性能;所以自旋锁的持有时间不能太长,只适合轻量级加锁,如果需要更长时间的场景,需要换其他方法。
1-> api
spainlock_t lock 定义自旋锁
spin_lock_init 初始化自旋锁
spin_lock 加锁
spin_unlock 释放锁
注意事项:
a.自旋锁在使用期间一定不能调用任何引起休眠和阻塞的api函数,否则会出现死锁;
b.会自动禁止抢占。
c. 如果线程A 持有自旋锁,发生中断,中断抢走cpu控制权,中断也要获得自旋锁,但这个锁被A占用,中断就会一直自旋,等待锁有效。在中断不执行玩,线程A是不可能执行的。会出现僵死的现象。

   2-> spin_lock_irq //禁止本地中断,并获取自旋锁。
   		spin_unlock_irq // 激活本地中断,并释放自旋锁。
   		spin_lock_irqsave //保护中断状态,禁止本地中断,并获取自旋锁。
   		spin_unclick_Irqrestore// 将中段恢复到之前的状态, 激活本地中断,并释放自旋锁

3.信号量
信号量是kernl的一种信号同步的机制,常常用于对共享资源的访问,能够提高处理器的使用效率。

			特点:
				a.相比于自旋锁,信号量可以使线程进入睡眠状态。
			    b. 不能用于中断,因为信号量会引起休眠,中断不能休眠。
			    c.信号量需要休眠,并且切换线程,开销大于优势。
		1->api 
		struct semaphore sem;//定义信号量

		sema_init(&sem,1); 申请信号量

		down(&sem);申请信号量
        up(&sem); 释放信号量

4.互斥锁
将信号量的值设为1就可以使用信号量进行互斥,互斥体是linux内核提供比信号量更专业的机制来进行互斥。
互斥体表示一次只能有一个线程来访问共享资源,不能递归申请互斥体。
注意事项:
a. mutex 可以导致休眠,不能用于中断
b. 和信号量一样,mutex保护的临界区可以调用引起api阻塞的函数
c. 不能递归上锁和解锁。

		1->api 函数
			struct mutex lock;//定义互斥体
			mutex_init(&lock); // 初始化互斥体
			mutex_lock(&lock); //上锁
			mutex_unlock(&lock); //解锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值