您的位置:首页 > 其它

互斥与同步

2013-06-03 14:26 183 查看
local_irq_enable与local_irq_disable

在单处理器不可抢占系统中,使用local_irq_enable与local_irq_disable是消除异步并发源的有效方式。

虽然驱动程序中应避免使用这两个宏,但在spinlock等互斥机制中常常用到这两个宏。

local_irq_save与local_irq_restore

防止在一个中断关闭环境中因为调用local_irq_disable与local_irq_enable将之前的中断响应状态破坏掉。

自旋锁

static inline void spin_lock(spinlock_t *lock)

{
raw_spin_lock(&lock->rlock);
}

static inline void raw_spin_lock(raw_spinlock_t *lock)

{
preempt_disable();
do_raw_spin_lock(lock);
}

raw_spin_lock要先调用preempt来关闭系统的可抢占性,为了保护共享资源不会收到破坏。

当知道一个自旋锁在终端上下文中有可能会被使用到时,应该使用spin_lock_irq函数。

还有一个类似变体,spin_lock_irqsave。另一个版本spin_lock_bh(spin_unlock_bh)的功能就是用来处理进程

与延迟处理导致的并发互斥问题。

即使在单处理器上只需调用local_irq_enable / local_irq_disable来对共享资源进行保护,也应该使用

spin_lock_irq / spin_unlock_irq函数,因为若将来代码移植到多处理器。

读取者与写入者自旋锁rwlock

read_lock_irq / read_unlock_irq

write_lock_irq / write_unlock_irq

信号量

信号量down操作

void down(struct semaphore *sem);

int down_interruptible(struct semaphore *sem);  //中断可中断

int down_trylock(struct semaphore *sem);  //不睡眠立即返回

int down_timeout(struct semaphore *sem):  //处于睡眠状态有时间限制

信号量up操作

up(struct semaphore *sem);


读取者与写入者信号量rwsem

读取者信号量down操作

void_sched  down_read(struct rw_semaphore * sem);

int down_read_trylock(struct rw_semaphore * sem);


读取者信号量up操作

void up_read(struct rw_semaphore * sem);

写入者信号量down操作

void_sched  down_write(struct rw_semaphore * sem);

int down_write_trylock(struct rw_semaphore * sem);

写入者信号量up操作

void up_write(struct rw_semaphore * sem);


互斥锁

互斥锁初始化

void mutex_init(struct mutex *lock);

互斥锁down操作

void_sched mutex_lock(struct mutex *lock);

互斥锁up操作

void_sched mutex_unlock(struct mutex *lock);


顺序锁

顺序锁设计思想,对某一共享数据读取时不加锁,写的时候加锁。为了保证读取时不会因为

写入者的出现导致该共享数据的更新,需要在读取者和写入者之间引入一整型变量,称为顺序

值,读取者在开始读取前读取该sequence,在读取后再重读该值,如果与读取之前的值不一致,

则说明本次读取过程中发生了数据更新,读取无效。

静态定义一个seqlock并初始化,可以使用

#define DEFINE_SEQLOCK(x)

动态初始化一个seqlock变量,可以使用

seqlock_init(x)

写入者顺序锁上锁操作

static inline void write_seqlock(seqlock_t *sl)

static inline void write_seqlock_irq(seqlock_t *sl)

static inline void write_seqlock_irqsave(seqlock_t *sl)

static inline void write_seqlock_bh(seqlock_t *sl)

static inline void write_tryseqlock(seqlock_t *sl)


写入者顺序锁的解锁操作

static inline void write_sequnlock(seqlock_t *sl)

static inline void write_sequnlock_irq(seqlock_t *sl)

static inline void write_sequnlock_irqrestore(seqlock_t *sl)

static inline void write_sequnlock_bh(seqlock_t *sl)


对于读取者顺序锁代码

例子:

do{

start = read_seqbegin(&demo_seqlock);

do_read();

}while( read_seqretry(&demo_seqlock, start) );

read_seqbegin_irqsave(lock, flags);

read_seqretry_irqrestore(lock,iv,flags);


原子变量操作

//Task A

void taska_addflag()

{  atomic_inc(&g_flag);  }

//Task B

void taskb_addflag()

{  atomic_inc(&g_flag);  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: