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);
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ps打开后 未响应怎么办 ps图层无法解锁怎么办 ie8浏览器电脑不能用怎么办 系统要ie6.0才能打开怎么办 2g手机内存不够怎么办 2g运行内存不够怎么办 手机运行内存2g不够怎么办 手机无法加载程序秒退怎么办 电脑账户密码忘记了怎么办 玩绝地求生卡顿怎么办 地下城总运行时间错误怎么办 逆战更新太慢怎么办 win7我的电脑没了怎么办 剑灵启动游戏慢怎么办 网页页面结束进程也关不掉怎么办 开机就启动微信怎么办 微信突然无法启动怎么办 微信发送太频繁怎么办 微信在电脑上打不开文件怎么办 微信照片电脑上打不开怎么办 换一部手机微信怎么办 微信支付宝停止运行怎么办 剑三重制版卡顿怎么办 剑三客户端更新不动了怎么办 安装包安装失败怎么办有内存 qq飞车换手机了怎么办 qq飞车求婚失败戒指怎么办 改脸型皮肤会下垂怎么办 情侣关系弄僵了怎么办 用微信交话费没有到账怎么办 微信交错话费了怎么办 微信缴费交错了怎么办 微信支付被投诉怎么办 微信q币充值错误怎么办 微信充值流量充错了怎么办 微信延迟到账怎么办 移动流量充错了怎么办 qq充话费等待发货怎么办 qq充值话费没到账怎么办 电信话费冲错了怎么办 微信手机充错话费充空号怎么办