并发与竞态及解决途径
来源:互联网 发布:多多返利网站源码 编辑:程序博客网 时间:2024/04/30 16:52
并发与竞态发生的条件:对称多处理器(SMP)的多个CPU;单CPU内进程与抢占它的进程;中断与进程之间。
解决并发与竞态的途径
访问共享资源的代码区域称为临界区域(criticalsection),解决竞态的根本途径就是对临界区的互斥访问,方法主要有中断屏蔽、原子操作、自旋锁、信号量、互斥体。
1、中断屏蔽
单CPU避免竞态的简单办法就是中断屏蔽,保证可以防止中断与进程间竞态条件的发生(所有中断被屏蔽后进程间切换的基础时钟中断也被屏蔽掉了)。
使用方法:
local_irq_disable()//禁止本地CPU的中断
......
critical section
......
local_irq_enable()
中断对保证系统正常运行非常重要,长时间屏蔽中断会让系统很危险。
2、原子操作
原子操作是指在执行过程中不会被别的代码路径所中断,可分为整形原子操作和位原子操作。
整形原子操作
atomic_t v;//定义原子变量v
void atomic_set(atomic_t *v, int i); //设置原子变量v的值为i
atomic_t v=ATOMIC_INT(0); //定义原子变量v,并初始化为0
atomic_read(atomic_t *v); //获取原子变量的值
void atomic_add(int i, atomic_t *v); //原子变量加i
void atomic_sub(int i, atomic_t *v); //原子变量减i
位原子操作
void set_bit(nr, void *addr); //设置addr指向的值的nr位为1
void clear_bit(nr, void *addr);
void change_bit(nr, void *addr); //第nr位取反
test_bit(nr, void *addr); //测试位
3、自旋锁
自旋锁主要针对SMP或单CPU且内核可抢占的情况,自旋锁可以保证临界区不受别的CPU和本CPU内的抢占进程打扰。当临界区可能受到中断和底半步影响时,应该使用自旋锁的衍生操作。
自旋锁是忙等待锁,当锁不可用时,CPU会不停地循环测试而不能做其它的工作,因此自旋锁会降低系统的性能。
如果临界区域发生阻塞,可能会导致死锁,因此在自旋锁占有期间内不能调用copy_from_user(),copy_to_user(), kmalloc()等函数
spinlock_t lock; //定义自旋锁
spin_lock_init(&lock);//初始化自旋锁
spin_lock(&lock);//获得自旋锁
spin_trylock(&lock);//尝试获得自旋锁
spin_unlock(&lock);//释放自旋锁
4、信号量
信号量和自旋锁不同的地方在于当进程得不到信号量时,进程会进入休眠或其它状态。
struct semaphore sem;//定义信号量
void sema_init(struct semaphore*sem, int val); //初始化信号量sem, 并把它的值设为val
DECLARE_MUTEX(name)//定义并初始化,相当于上面两句
DECLARE_MUTEX_LOCKED(name)//定义并初始化
void down(struct semaphore *sem);// 获得信号量,不能在中断上下文中使用,进入睡眠后不能用信号打断
int down_interruptible(structsemaphore *sem); //进入睡眠后可被信号打断
int down_trylock(struct semaphore*sem); //尝试获得信号量,不会睡眠,可以在中断上下文中使用
void up(struct semaphore *sem);//释放信号量
5、互斥体
互斥体完成的功能与信号量非常相识。
struct mutex my_mutex;//定义互斥体
mutex_init(&my_mutex); //初始化互斥体
void fastcall mutex_lock(structmutex *lock); //获取互斥体
int fastcallmut当ex_lock_interruptiable(structmutex *lock);
int fastcallmytex_trylock(struct mutex*lock);
void fastcallmutex_unlock(struct mutex*lock); //释放互斥体
自旋锁VS信号量
当临界区执行时间比较小时,采用自旋锁,否则采用信号量;
自旋锁绝对不能在临界区包含可能引起阻塞的代码,信号量可以;
如果临界区的代码在中断中执行,应该使用自旋锁或信号量的down_trylock()函数。- 并发与竞态及解决途径
- 并发与竞态及解决途径
- 并发与竞态及解决途径
- 烟草企业客户关系管理现状及解决途径
- 【浅析Windows系统下光驱常见问题及解决途径】
- WinXP系统CPU使用率高的缘由及解决途径
- 并发及竞态
- ActionController::InvalidAuthenticityToken解决途径
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 并发与竞态
- 竞态与并发
- 最简单的 Git 使用流程
- 通用设备的动态DMA映射
- 通用设备的动态DMA映射
- Linux芯片级移植与底层驱动(基于3…
- Linux芯片级移植与底层驱动(基于3…
- 并发与竞态及解决途径
- 在开关电源中 反馈电压分压电阻接输出的一个电阻并联一个电容的作用是什么。如图中C1就是一个例子
- 并发与竞态及解决途径
- Device drivers on SMP systems
- Device drivers on SMP systems
- linux中断嵌套以及中断丢失
- linux中断嵌套以及中断丢失
- ldd3学习之七:中断处理
- ldd3学习之七:中断处理