Linux系统的各类同步机制
一、锁机制:1、自旋锁:spinlock_t lock=SPIN_LOCK_UNLOCKED;spi_lock_init(&lock);spin_lock(&lock);spin_trylock(&lock);spin_unlock(&lock);spin_lock_irq();spin_lock_bh(&lock);//软件中断安全版本的自旋锁。2、读
·
一、锁机制:
1、自旋锁:
spinlock_t lock=SPIN_LOCK_UNLOCKED;
spi_lock_init(&lock);
spin_lock(&lock);
spin_trylock(&lock);
spin_unlock(&lock);
spin_lock_irq();
spin_lock_bh(&lock);//软件中断安全版本的自旋锁。
2、读写锁:可以多个读,但是只能一个写,且读写不能同时进行
rwlock_t lock=RW_LOCK_UNLOCKED;
rwlock_init(lock);
read_lock(&lock);
read_unlock(&lock);
write_lock(&lock);
write_unlock(&lock);
3、RCU:(read-copy update)// 不能直接写,要先复制一个副本等待时机再写入,因此试用读多写少的。
rcu_read_lock();
rcu_read_unlock();
调用回调函数写入:void call_rcu(struct rcu_head *head,void(*func)(void* arg),void* arg);
二、互斥:
1、原子操作:不可中断的。需硬件支持,否则容易被打断。
atomic_read(atomic_t *v);
atomic_set(atomic_t *v,int i);
atomic_add(int i,atomic_t *v);
atomic_sub(int i,atomic_t *v);
int set_bit(int nr,void addr);
int clear_bit(int nr,void addr);
int test_bit(int nr,void addr);
int change_bit(int nr,void addr);
2、信号量:与自旋锁差别:能导致睡眠。
void sema_init(struct semaphore * sem,int val);
互斥对象mutex是一种特殊的信号量,同一时刻只能一种访问,int val=1;
int_MUTEX(struct semaphore *sem); <==>sema_init(sem,1);
int_MUTEX_LOCKED(struct semaphore *sem); <==>sema_init(sem,0);
void down(struct semaphore *sem); //会导致睡眠。不能在中断上下文使用。
void up(struct semaphore *sem);
void down_trylock(struct semaphore *sem); //用在中断上下文。
void down_interruptible(struct semaphore *sem);
3、读写信号量,与读写锁类似。
void init_rwsem(struct rw_semaphore * sem);
void down_read(struct rw_semaphore * sem);
int down_read_trylock(struct rw_semaphore * sem);
void up_read(struct rw_semaphore * sem);
void down_write(struct rw_semaphore * sem);
int down_write_trylock(struct rw_semaphore * sem);
void up_write(struct rw_semaphore * sem);
void downgrade_write(struct rw_semaphore * sem);
三、等待队列
1、
void init_waitqueque_head(wait_queque_head_t *q);
wait_event(wq,condition);
wait_event_interruptible(wq,condition);
wait_event_timeout(wq,condition,timeout);
wait_event_interruptible_timeout(wq,condition,timeout);
wake_up(wait_queque_head_t *q);
wake_up_interruptible(wait_queque_head_t *q);
2、阻塞型设备驱动:
init()
{
int_MUTEX(struct semaphore *sem);
void init_waitqueque_head(wait_queque_head_t *q);
}
read()
{
wait_event_interruptible(wq,condition);
void down_interruptible(struct semaphore *sem);
void up(struct semaphore *sem);
}
write()
{
void down_interruptible(struct semaphore *sem);
wake_up_interruptible(wait_queque_head_t *q);
void up(struct semaphore *sem);
}
3、完成事件:它允许一个进程告诉另一个进程某些工作已经完成。
struct completion comp;
int()
{
void int_completion(&comp);
//DECLARE_COMPLETION(my_comp);//静态初始化。
}
read()
{
wait_for_completion(&comp);
wait_for_completion_interruptible(&comp);//可中断。
unsigned long wait_for_completion_timeout(&comp,unsigned long timeout);//可中断。
}
write()
{
complete(&comp);//唤醒一个等待完成事件的进程
complete_all(&comp);//唤醒所有等待进程。
}
4、关闭中断
void disable_irq(int irq);//禁止单个中断,等待成功返回。
void disable_irq_nosync(int irq);禁止单个中断,不等待成功返回。
void enable_irq(int irq);//允许单个中断。
void local_irq_save(unsigned long flags);//禁止所有中断,并保持标志。
void local_irq_disable(unsigned long flags);//禁止所有中断
void local_irq_restore(unsigned long flags);//使能所有中断,并恢复标志。
void local_irq_enable(unsigned long flags);//使能所有中断
1、自旋锁:
spinlock_t lock=SPIN_LOCK_UNLOCKED;
spi_lock_init(&lock);
spin_lock(&lock);
spin_trylock(&lock);
spin_unlock(&lock);
spin_lock_irq();
spin_lock_bh(&lock);//软件中断安全版本的自旋锁。
2、读写锁:可以多个读,但是只能一个写,且读写不能同时进行
rwlock_t lock=RW_LOCK_UNLOCKED;
rwlock_init(lock);
read_lock(&lock);
read_unlock(&lock);
write_lock(&lock);
write_unlock(&lock);
3、RCU:(read-copy update)// 不能直接写,要先复制一个副本等待时机再写入,因此试用读多写少的。
rcu_read_lock();
rcu_read_unlock();
调用回调函数写入:void call_rcu(struct rcu_head *head,void(*func)(void* arg),void* arg);
二、互斥:
1、原子操作:不可中断的。需硬件支持,否则容易被打断。
atomic_read(atomic_t *v);
atomic_set(atomic_t *v,int i);
atomic_add(int i,atomic_t *v);
atomic_sub(int i,atomic_t *v);
int set_bit(int nr,void addr);
int clear_bit(int nr,void addr);
int test_bit(int nr,void addr);
int change_bit(int nr,void addr);
2、信号量:与自旋锁差别:能导致睡眠。
void sema_init(struct semaphore * sem,int val);
互斥对象mutex是一种特殊的信号量,同一时刻只能一种访问,int val=1;
int_MUTEX(struct semaphore *sem); <==>sema_init(sem,1);
int_MUTEX_LOCKED(struct semaphore *sem); <==>sema_init(sem,0);
void down(struct semaphore *sem); //会导致睡眠。不能在中断上下文使用。
void up(struct semaphore *sem);
void down_trylock(struct semaphore *sem); //用在中断上下文。
void down_interruptible(struct semaphore *sem);
3、读写信号量,与读写锁类似。
void init_rwsem(struct rw_semaphore * sem);
void down_read(struct rw_semaphore * sem);
int down_read_trylock(struct rw_semaphore * sem);
void up_read(struct rw_semaphore * sem);
void down_write(struct rw_semaphore * sem);
int down_write_trylock(struct rw_semaphore * sem);
void up_write(struct rw_semaphore * sem);
void downgrade_write(struct rw_semaphore * sem);
三、等待队列
1、
void init_waitqueque_head(wait_queque_head_t *q);
wait_event(wq,condition);
wait_event_interruptible(wq,condition);
wait_event_timeout(wq,condition,timeout);
wait_event_interruptible_timeout(wq,condition,timeout);
wake_up(wait_queque_head_t *q);
wake_up_interruptible(wait_queque_head_t *q);
2、阻塞型设备驱动:
init()
{
int_MUTEX(struct semaphore *sem);
void init_waitqueque_head(wait_queque_head_t *q);
}
read()
{
wait_event_interruptible(wq,condition);
void down_interruptible(struct semaphore *sem);
void up(struct semaphore *sem);
}
write()
{
void down_interruptible(struct semaphore *sem);
wake_up_interruptible(wait_queque_head_t *q);
void up(struct semaphore *sem);
}
3、完成事件:它允许一个进程告诉另一个进程某些工作已经完成。
struct completion comp;
int()
{
void int_completion(&comp);
//DECLARE_COMPLETION(my_comp);//静态初始化。
}
read()
{
wait_for_completion(&comp);
wait_for_completion_interruptible(&comp);//可中断。
unsigned long wait_for_completion_timeout(&comp,unsigned long timeout);//可中断。
}
write()
{
complete(&comp);//唤醒一个等待完成事件的进程
complete_all(&comp);//唤醒所有等待进程。
}
4、关闭中断
void disable_irq(int irq);//禁止单个中断,等待成功返回。
void disable_irq_nosync(int irq);禁止单个中断,不等待成功返回。
void enable_irq(int irq);//允许单个中断。
void local_irq_save(unsigned long flags);//禁止所有中断,并保持标志。
void local_irq_disable(unsigned long flags);//禁止所有中断
void local_irq_restore(unsigned long flags);//使能所有中断,并恢复标志。
void local_irq_enable(unsigned long flags);//使能所有中断
更多推荐
已为社区贡献1条内容
所有评论(0)