##原子操作##
“原子”不可分割,原子操作,就是不能被分割的指令。
原子类型实际上是一个整数:
typedef struct {
volatile int counter;
} atomic_t;
使用
定义
atomic_t v;
atomic_t u=ATOMIC_INIT(0);//定义并初始化
atomic_set(&v,4);
atomic_add(2,&v);
atomic_inc(&v);
/*将给定的原子变量减1,如果结果为0,就返回真,否则返回假*/
int atomic_dec_and_test(atomic_t *v);
还有其他原子操作,参见文件<asm/atomic.h>
##自旋锁–spin lock##
自旋:如果一个执行线程试图获得一个已经被持有的的自旋锁,那么该线程就会一直进行忙-旋转-等待锁重新可用。
定义和初始化
方式1:
spinlock_t spinlock = SPIN_LOCK_UNLOCKED;
方式2:
spinlock_t spinlock ;
spin_lock_init(spinlock )
方式3:
DEFINE_SPINLOCK(mr_lock)
使用
spin_lock(&mr_lock,flags);
/*临界区*/
spin_unlock(&mr_lock,flags);
自旋锁可以使用在中断处理函数中,在中断处理中使用自旋锁时一定要注意:在获取锁之前首先禁止本地中断(在当前处理器上的中断请求),否则,中断处理程序就会打断正持有的内核代码,有可能会试图去征用这个已经被持有的自旋锁,这样一来,中断处理程序就会自旋,等待该锁重新可用,但是锁的持有者在这个中断处理程序执行完毕前不能能运行,造成双重请求死锁;
unsigned long long flags;
spin_lock_irqsave(&mr_lock,flags);
/*临界区*/
spin_unlock_irqrestore(&mr_lock,flags);
spin_lock_irqsave()保存中断的当前状态,并禁止本地中断,然后再去获取执行的锁,spin_unlock_irqrestore()对指定的锁解锁,让中断恢复到加锁之前的状态。
其他使用方法可以参考内核源码<asm/atomic.h>找到
##信号量##
信号量是一种睡眠锁
定义和初始化
方式1:
struct semaphore name;
sema_init(&name, count);
方式2:
static DECLARE_MUTEX(name);
方式3:
init_MUTEX(sem);
其中sem是指针,指向动态分配的信号量,计数初始化为1
具体实现定义再文件<asm/semaphore.h>中
使用方式
down_interruptible(struct semaphore*)
down(struct semaphore*)
down_trylock(struct semaphore*)
up(struct sempahore*)
##互斥体mutex##
相当于计数为1的信号量,但是只能在同一个上下文中使用
定义和初始化
方式1:
DEFINE_MUTEX(name)
方式2:
mutex_init(&mutex);
使用方式
mutex_lock(struct mutex*)
mutex_unlock(struct mutex*)
mutex_trylock(struct mutex*)
mutex_is_locked(struct mutex*)