Linux设备驱动中的并发控制

1.并发是指多个执行单元同时、并行的执行。并发的执行单元对共享资源的访问很容易导致竞态。

在 Linux 内核中,主要的竞态发生于如下几种情况:

①对称多处理器(SMP)的多个 CPU

②单CPU内进程与抢占它的进程

③中断(硬中断、软中断、Tasklet、底半部)与进程之间

2.解决竞态的方法

中断屏蔽

中断屏蔽的使用方法为:

local_irq_disable() //屏蔽中断

critical section //临界区

local_irq_enable() //开中断

原子操作:原子操作指的是在执行过程中不会被别的代码路径所中断的操作。

void atomic_set(atomic_t *v, int i); //设置原子变量的值为 i

atomic_read(atomic_t *v);//读取原子变量的值

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

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

void atomic_inc(atomic_t *v);//自加

void atomic_dec(atomic_t *v);//自减

操作并测试

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);

上述操作对原子变量执行自增、自减和减操作后(注意没有加)测试其是否为 0,为 0 则返回 true,否则返回 false。

位原子操作

void set_bit(nr,void *addr);//设置位,nr为地址的第nr位

void clear_bit(nr,void *addr);//清除位

void change_bit(nr, void *addr);//改变位

test_bit(nr, void *addr);//测试位

自旋锁:一种对临界资源进行互斥手访问的典型手段.、

spinlock_t spin;//自定义自旋锁

spin_lock_init(lock);//初始化

spin_lock(lock)//获得自旋锁、

spin_unlock(lock)//释放自旋锁

驱动工程师应谨慎使用自旋锁,而且在使用中还要特别注意 自旋锁实际上是忙等锁,自旋锁可能导致系统死锁 这两个问题.

读写自旋锁

rwlock_t lock;//定义rwlock

rwlock_init(&lock);//初始化

read_lock(&lock);//读时获取锁

read_ulock(&lock);//

write_lock_irqsave(&lock, flags);//写时获取锁
write_unlock_irqrestore(&lock, flags);

顺序锁:顺序锁(seqlock)是对读写锁的一种优化,若使用顺序锁,读执行单元绝不会被写执行单元阻塞------略

信号量的使用:与自旋锁不同的是,当获取不到信号量时,进程不会原地打转而是进入休眠等待状态。

struct semaphore sem;//定义信号量

void sema_init(struct semaphore *sem,int var);//初始化信号量

void down(struct semaphore * sem);//获取信号量、进入睡眠状态的进程不能被信号打断

void up(struct semaphore * sem);//释放信号量

完成量用于同步

struct completion my_completion;//定义完成量

init_completion(&my_completion);//初始化完成量

void wait_for_completion(struct completion *c);//等待完成量

void complete_all(struct completion *c);//唤醒完成量

信号量vs自旋锁

信号量是进程间用于对资源的互斥,如果竞争失败,进程进入睡眠状态

自旋锁访问时间要短,节省上下文切换的时间。CPU得不到自旋锁不停止。

11互斥体

struct mutex my_mutex;//定义

mutex_init(&my_mutex);//初始化

mutex_lock(&my_mutex); //获取 mutex、

mutex_unlock(&my_mutex); //释放 mutex

上一篇:测试驱动开发TDD(test drive development)


下一篇:python zip enumerate函数