linux设备驱动的并发控制
来源:互联网 发布:地下室js防水涂料 厚度 编辑:程序博客网 时间:2024/06/06 05:32
一、中断屏蔽
中断屏蔽的使用方法:
local_irq_disable();//屏蔽中断
....//临界区处理
local_irq_enable();//开中断
注:local_irq_disable()和local_irq_enable()只能禁止和使能本CPU内的中断.
local_irq_save(flags);//禁止中断并保存当前CPU的中断位信息
local_irq_restore(flags);//恢复中断
local_bh_disable();//禁止中断低半部
local_bh_disable();//恢复中断低半部
二、原子操作
1、整形原子操作
1)设置原子变量的值
void atomic_set(atomic_t *v,int i);//设置原子变量的值为i
atomic_t v=ATOMIC_INIT(0);//定义原子变量V并初始化为0
2)获取原子变量的值
atomic_read(atomic_t *v);//返回原子变量的值
3)原子变量的加/减
void atomic_add(int i,atomic_t *v);//原子变量加i
void atomic_sub(int i,atomic_t *v);//原子变量减i
4)原子变量自增/减
void atomic_inc(atomic_t *v);//原子变量增加1
void atomic_dec(atomic_t *v);//原子变量减1
5)操作并测试
int atomic_inc_and_test(atomic_t *v);//操作并测试是否为0
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(int i,atomic_t *v);
6)操作并返回
int atomic_add_return(int i,atomic_t *v);
int atomic_sub_return(int i,atomic_t *v);
int atomic_inc_return(atomic_t *v);
int atomic_dec_return(atomic_t *v);
2、位原子操作
1)设置位
void set_bit(nr,void *addr);//将addr的第nr位设置为1
2)清楚位
void clear_bit(nr,void *addr);//将addr的第nr为设置为0
3)改变位
void change_bit(nr,void *addr);//将addr的第n位进行反置
4)测试位
test_bit(nr,void *addr);//返回addr的第nr位
5)测试并操作位
int test_and_set_bit(nr,void *addr);
int test_and_clear_bit(nr,void *addr);
int test_and_change_bit(nr,void *addr);
三、自旋锁
1、定义自旋锁
spinlock_t lock;
2、初始化自旋锁
spin_lock_init(lock);
3、获取自旋锁
spin_lock(lock);
spin_trylock(lock);//尝试获得自旋锁,如不能获得立即返回
4、释放自旋锁
spin_unlock(lock);
5、自旋锁的使用
spinlock_t lock;
spin_lock_init(&lock);
spin_lock(&lock);
....//临界操作
spin_unlock(lock);
6、自旋锁和中断使用
spin_lock_irq()=spin_lock()+local_irq_diable()
spin_unlock_irq()=spin_unlock()+local_irq_enable()
spin_lock_irqsave()=spin_lock()+local_irq_save()
spin_unlock_irqrestore()=spin_unlock()+local_irq_retore()
spin_lock_bh()=spin_lock()+local_bh_diable()
spin_unlock_bh()=spin_unlock()+local_bh_enable()
四、读写自旋锁
1、定义和初始化读写自旋锁
rwlock_t my_rwlock=W_LOCK;//静态初始化
rwlock_t my_rwlock;
rwlock_init(&my_rwlock);//动态初始化
2、读锁定
void read_lock(rwlock_t *lock);
void read_lock_irqsave(rwlock_t *lock,unsigned long flags);
void read_lock_irq(rwlock_t *lock);
void read_lock_bh(rwlock_t *lock);
3、读解锁
void read_unlock(rwlock_t *lock);
void read_unlock_irqretore(rwlock_t *lock,unsigned long flags);
void read_unlock_irq(rwlock_t *lock);
void read_unlock_bh(rwlock_t *lock);
4、写锁定
void write_lock(rwlock_t *lock);
void write_lock_irqsave(rwlock_t *lock,unsigned long flags);
void write_lock_irq(rwlock_t *lock);
void write_lock_bh(rwlock_t *lock);
int write_trylock(rwlock_t *lock);
5、写解锁
void write_unlock(rwlock_t *lock);
void write_unlock_irqretore(rwlock_t *lock,unsigned long flags);
void write_unlock_irq(rwlock_t *lock);
void write_unlock_bh(rwlock_t *lock);
6、读写自旋锁的使用
rwlock_t lock;//定义自旋锁
rwlock_init(&lock);//初始化自旋锁
read_lock(&lock);//读时锁定
...//临界操作
read_unlock(&lock);//读解锁
write_lock_irqsave(&lock,flags);//写锁定
...//写锁定
write_unlock_irqretore(&lock,flags);//写解锁
五、顺序锁
1、获得顺序锁
void write_seqlock(seqlock_t *sl);
int write_tryseqlock(seqlock_t *sl);
write_seqlocl_irqsave(lock,flags);
write_seqlocl_irq(lock);
write_seqlocl_bh(lock);
2、释放顺序锁
void write_sequnlock(seqlock_t *sl);
write_sequnlocl_irqretore(lock,flags);
write_sequnlocl_irq(lock);
write_sequnlocl_bh(lock);
3、写顺序锁的使用
write_seqlock(&sl);
...//临界操作
write_sequnlock(&sl);
4、读开始
unsigned read_seqbegin(const seqlock_t *sl);
read_seqbegin_irqsave(lock,flags);
5、重读
int read_seqretry(const seqlock_t *sl,unsigned lv);
read_seqretry_irqrestore(lock,lv,flags);
6、读顺序锁的使用
do{
seqnum=read_seqbegin(&seqlock_a);
}while(read_seqretry(&seqlock_a,seqnum));
六、信号量
1、定义信号量
struct semaphore sem;
2、初始化信号量
void sem_init(struct semaphore *sem,int val);
3、获得信号量
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);//可被信号打断
int down_trylock(struct semaphore *sem);
4、释放信号量
void up(struct semaphore *sem);
5、信号量的使用
DECLARE_MUTEX(sem);
down(&sem);//获得信号量
...//临界操作
up(&sem);
七、完成量
1、定义完成量
struct completion my_completion;
2、初始化完成量
init_completion(&my_completion);
3、等待完成量
void completion(struct completion *my_completion);
void completion_all(struct completion *my_completion);
八、互斥体
1、初始化互斥体
struct mutex my_mutex;
mutex_init(&my_mutex);
2、获取互斥体
void inline __sched mutex_lock(struct mutex *my_mutex);
int __sched mutex_lock_interuptible(struct mutex *my_mutex);
int __sched mutex_trylock(struct mutex *my_mutex);
3、释放互斥体
void __sched mutex_unlock(struct mutex *my_mutex);
4、互斥体的使用
struct mutex my_mutex;
mutex_init(&my_mutex);
mutex_lock(&my_mutex);
...//临界操作
mutex_unlock(&my_mutex);
中断屏蔽的使用方法:
local_irq_disable();//屏蔽中断
....//临界区处理
local_irq_enable();//开中断
注:local_irq_disable()和local_irq_enable()只能禁止和使能本CPU内的中断.
local_irq_save(flags);//禁止中断并保存当前CPU的中断位信息
local_irq_restore(flags);//恢复中断
local_bh_disable();//禁止中断低半部
local_bh_disable();//恢复中断低半部
二、原子操作
1、整形原子操作
1)设置原子变量的值
void atomic_set(atomic_t *v,int i);//设置原子变量的值为i
atomic_t v=ATOMIC_INIT(0);//定义原子变量V并初始化为0
2)获取原子变量的值
atomic_read(atomic_t *v);//返回原子变量的值
3)原子变量的加/减
void atomic_add(int i,atomic_t *v);//原子变量加i
void atomic_sub(int i,atomic_t *v);//原子变量减i
4)原子变量自增/减
void atomic_inc(atomic_t *v);//原子变量增加1
void atomic_dec(atomic_t *v);//原子变量减1
5)操作并测试
int atomic_inc_and_test(atomic_t *v);//操作并测试是否为0
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(int i,atomic_t *v);
6)操作并返回
int atomic_add_return(int i,atomic_t *v);
int atomic_sub_return(int i,atomic_t *v);
int atomic_inc_return(atomic_t *v);
int atomic_dec_return(atomic_t *v);
2、位原子操作
1)设置位
void set_bit(nr,void *addr);//将addr的第nr位设置为1
2)清楚位
void clear_bit(nr,void *addr);//将addr的第nr为设置为0
3)改变位
void change_bit(nr,void *addr);//将addr的第n位进行反置
4)测试位
test_bit(nr,void *addr);//返回addr的第nr位
5)测试并操作位
int test_and_set_bit(nr,void *addr);
int test_and_clear_bit(nr,void *addr);
int test_and_change_bit(nr,void *addr);
三、自旋锁
1、定义自旋锁
spinlock_t lock;
2、初始化自旋锁
spin_lock_init(lock);
3、获取自旋锁
spin_lock(lock);
spin_trylock(lock);//尝试获得自旋锁,如不能获得立即返回
4、释放自旋锁
spin_unlock(lock);
5、自旋锁的使用
spinlock_t lock;
spin_lock_init(&lock);
spin_lock(&lock);
....//临界操作
spin_unlock(lock);
6、自旋锁和中断使用
spin_lock_irq()=spin_lock()+local_irq_diable()
spin_unlock_irq()=spin_unlock()+local_irq_enable()
spin_lock_irqsave()=spin_lock()+local_irq_save()
spin_unlock_irqrestore()=spin_unlock()+local_irq_retore()
spin_lock_bh()=spin_lock()+local_bh_diable()
spin_unlock_bh()=spin_unlock()+local_bh_enable()
四、读写自旋锁
1、定义和初始化读写自旋锁
rwlock_t my_rwlock=W_LOCK;//静态初始化
rwlock_t my_rwlock;
rwlock_init(&my_rwlock);//动态初始化
2、读锁定
void read_lock(rwlock_t *lock);
void read_lock_irqsave(rwlock_t *lock,unsigned long flags);
void read_lock_irq(rwlock_t *lock);
void read_lock_bh(rwlock_t *lock);
3、读解锁
void read_unlock(rwlock_t *lock);
void read_unlock_irqretore(rwlock_t *lock,unsigned long flags);
void read_unlock_irq(rwlock_t *lock);
void read_unlock_bh(rwlock_t *lock);
4、写锁定
void write_lock(rwlock_t *lock);
void write_lock_irqsave(rwlock_t *lock,unsigned long flags);
void write_lock_irq(rwlock_t *lock);
void write_lock_bh(rwlock_t *lock);
int write_trylock(rwlock_t *lock);
5、写解锁
void write_unlock(rwlock_t *lock);
void write_unlock_irqretore(rwlock_t *lock,unsigned long flags);
void write_unlock_irq(rwlock_t *lock);
void write_unlock_bh(rwlock_t *lock);
6、读写自旋锁的使用
rwlock_t lock;//定义自旋锁
rwlock_init(&lock);//初始化自旋锁
read_lock(&lock);//读时锁定
...//临界操作
read_unlock(&lock);//读解锁
write_lock_irqsave(&lock,flags);//写锁定
...//写锁定
write_unlock_irqretore(&lock,flags);//写解锁
五、顺序锁
1、获得顺序锁
void write_seqlock(seqlock_t *sl);
int write_tryseqlock(seqlock_t *sl);
write_seqlocl_irqsave(lock,flags);
write_seqlocl_irq(lock);
write_seqlocl_bh(lock);
2、释放顺序锁
void write_sequnlock(seqlock_t *sl);
write_sequnlocl_irqretore(lock,flags);
write_sequnlocl_irq(lock);
write_sequnlocl_bh(lock);
3、写顺序锁的使用
write_seqlock(&sl);
...//临界操作
write_sequnlock(&sl);
4、读开始
unsigned read_seqbegin(const seqlock_t *sl);
read_seqbegin_irqsave(lock,flags);
5、重读
int read_seqretry(const seqlock_t *sl,unsigned lv);
read_seqretry_irqrestore(lock,lv,flags);
6、读顺序锁的使用
do{
seqnum=read_seqbegin(&seqlock_a);
}while(read_seqretry(&seqlock_a,seqnum));
六、信号量
1、定义信号量
struct semaphore sem;
2、初始化信号量
void sem_init(struct semaphore *sem,int val);
3、获得信号量
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);//可被信号打断
int down_trylock(struct semaphore *sem);
4、释放信号量
void up(struct semaphore *sem);
5、信号量的使用
DECLARE_MUTEX(sem);
down(&sem);//获得信号量
...//临界操作
up(&sem);
七、完成量
1、定义完成量
struct completion my_completion;
2、初始化完成量
init_completion(&my_completion);
3、等待完成量
void completion(struct completion *my_completion);
void completion_all(struct completion *my_completion);
八、互斥体
1、初始化互斥体
struct mutex my_mutex;
mutex_init(&my_mutex);
2、获取互斥体
void inline __sched mutex_lock(struct mutex *my_mutex);
int __sched mutex_lock_interuptible(struct mutex *my_mutex);
int __sched mutex_trylock(struct mutex *my_mutex);
3、释放互斥体
void __sched mutex_unlock(struct mutex *my_mutex);
4、互斥体的使用
struct mutex my_mutex;
mutex_init(&my_mutex);
mutex_lock(&my_mutex);
...//临界操作
mutex_unlock(&my_mutex);
0 0
- linux设备驱动的并发控制
- linux设备驱动的并发控制
- Linux 设备驱动的并发控制
- Linux 设备驱动的并发控制
- Linux设备驱动的并发控制总结
- Linux 设备驱动的并发控制
- Linux设备驱动并发控制
- 对linux设备驱动中的并发控制相关内容的理解
- 深入浅出Linux设备驱动之并发控制
- Linux设备驱动中的并发控制
- 深入浅出Linux设备驱动之并发控制
- 深入浅出Linux设备驱动之并发控制
- Linux设备驱动中的并发控制
- Linux 设备驱动中的并发控制
- Linux设备驱动之并发控制(1)
- linux设备驱动中的并发控制
- Linux设备驱动中的并发控制
- 7、linux设备驱动--并发控制
- 网络131计算圆面积
- C#线程通信和异步委托
- 僜的2244
- adb常用命令整理
- Repeater控件如何让变量自增 asp.net
- linux设备驱动的并发控制
- 细数二十世纪最伟大的10大算法
- UVA 11916 Emoogle Grid(离散对数)
- Medoo Max的使用:取出被查询字段中的最大值
- 互联网思维下的传统企业转型思考
- 谈成来让他的人给他送
- ACM 房间安排
- C++常用的语法
- 深入浅出 - Android系统移植与平台开发(六)- 搭建基于Linux的Android开发环境