Linux中的同步问题(Linux驱动1)
来源:互联网 发布:淘宝轮毂能买吗 编辑:程序博客网 时间:2024/06/06 00:02
操作系统中存在竞态问题,就是同时访问共享资源(包括程序,数据),引起竞态的原因有:smp,抢占式内核,中断(硬中断,软中断等).
抢占式内核竞态问题的图示:
假如代码如下:
write(resource);
write_count++;
A进程 B进程 C进程------------------------------------------------------写 ------------------------------------------------------ 写----------------------------------------------------- 计数 =1 ------------------------------------------------ 读计数(这时,就有问题)----------------------------------------------------- 计数=2---------------------------------------------------
问题:进程c读计数时,实际写了两次,可是这里读计数只有1次,问题产生的原因就在于写和计数不是原子操作)。
保护共享资源的方法有:中断屏蔽,原子操作,锁,信号量.
1 中断屏蔽
变量函数 local_irq_enable local_irq_disable用法 local_irq_disable .... local_irq_enable扩展: local_irq_save(flags) local_irq_restore(flags) local_bh_enable local_bh_disable
2原子操作
说明:原子操作,不会被打断变量: atomic_t ATOMIT_INIT(i) 初始化值函数 atomic_inc(atomic_t*) atomic_dec(atomic_t*) atomic_add(int,atomic_t*) atomic_sub(int,atomic_t*) atomic_read(atomic_t*) atomic_inc_and_test(atomic_t*) atomic_dec_and_test(atomic_t*) atomic_sub_and_test(int,atomic_t*) 注意,没有加 atomic_inc_return(atomic_t*) atomic_dec_return(atomic_t*) atomic_add_return(int,atomic_t*) atomic_sub_return(int,atomic_t*) bit操作 set_bit(nr,void*) clear_bit(nr,void*) change_bit(nr,void*) test_bit(nr,void*) test_and_set(nr,void*) 先测试,再操作 test_and_clear(nr,void*) test_and_change(nr,void*)
3 自旋锁
说明: 自旋锁会在原地打转,所以临界区尽可能短,不能阻塞.变量: spinlock_t lock函数 spin_lock_init(spinlock_t*) spin_lock(spinlock_t*) spin_unlock(spinlock_t*)用法 spinlock_t lock spin_lock_init(&lock) spin_lock(&lock) ... spin_unlock(&lock)扩展 spin_trylock(&lock) spin_lock_irq(&lock) spin_unlock_irq(&lock) spin_lock_irqsave(&lock,flags) spin_unlock_irqrestore(&lock,flags) spin_lock_bh(&lock) spin_unlock_bh(&lock) 读写自旋锁
说明:读写锁是比自旋锁粒度更小的锁,自旋锁对于读写不加区分,而实际上对于读操作是可以并发的,读写锁就是解决这个问题。当然,读和写也是不能同时进行的。
变量: rwlock_t lock=RW_LOCK_UNLOCKED;静态初始化 函数 rwlock_init(rwlock_t*)动态初始化 read_lock(rwlock_t*) read_unlock(rwlock_t*) write_lock(rwlock_t*) write_unlock(rwlock_t*) 用法 rwlock_t lock; rwlock_init(&lock) 读自旋锁 read_lock(&lock) ... read_unlock(&lock) 写自旋锁 write_lock(&lock) ... write_unlock(&lock) 扩展 read_lock_irq(&lock) read_unlock_irq(&lock) read_lock_irqsave(&lock,flags) read_unlock_irqrestore(&lock,flags) read_lock_bh(&lock) read_unlock_bh(&lock) write_lock_irq(&lock) write_unlock_irq(&lock) write_lock_irqsave(&lock,flags) write_unlock_irqrestore(&lock,flags) write_lock_bh(&lock) write_unlock_bh(&lock)
4 顺序锁
说明:顺序锁是读写锁的优化,读单元不会被写单元阻塞,写单元也不会被读单元阻塞。但是写单元之间仍然是互斥的。顺序锁有一个限制就是不能在其中使用指针,因为在保护的写单元中可能会使指针失效,而读单元此时使用指针就会失效。
变量: seqlock_t lock; 函数: write_seqlock(&lock) write_sequnlock(&lock) write_seqtrylock(&lock) read_seqbegin(&lock) read_seqretry(&lock,iv) 用法: 写操作 write_seqlock ... write_sequnlock 读操作 do{ seqnum=read_seqbegin(&lock); .... }while(read_seqretry(&lock,sequm)) 扩展: write_seqlock_irq(&lock) write_sequnlock_irq(&lock) write_seqlock_irqsave(&lock,falgs) write_sequnlock_irqrestore(&lock,falgs) write_seqlock_bh(&lock) write_sequnlock_bh(&lock) read_seqbegin_irqsave(&lock,falgs) read_seqretry_irqrestore(&lock,iv,flags)
6 RCU
说明:rcu是read copy update的意思,可以看做是读写锁的高级版本,可以对保护单元同时进行读写.
变量:rcu_head head 函数: read_lock_rcu() read_unlock_rcu() call_rcu(struct rcu_head*,void(*fun)(struct rcu_head*)) 用法: read_lock_rcu ... read_unlock_rcu 扩展 list_add_rcu list_add_tail_rcu list_del_rcu list_replace_rcu list_for_each_rcu list_for_each_safe_rcu list_for_each_entry_rcu hlist_add_head_rcu hlist_del_rcu hlist_for_each_rcu hlost_for_each_entry_rcu
7 信号量
说明: 信号量与自旋锁不同,信号量会进入休眠状态,而自旋锁会在原地打转. 变量: semaphore sem;函数: sema_init(struct semaphore *,int val) DECLARE_MUTEX(name) DECLARE_MUTEX_LOCKED(name) init_MUTEX(&sem) init_MUTEX_LOCKED(&sem) down(&sem) up(&sem)用法: down .... up扩展:
down_interruptible(&sem) 进入浅睡眠状态,可被打断.当调用此函数时需要检查其返回值如果返回非0,应当返回-ERESTARTSYS
down_trylock 尝试获得信号量,如果获得则立即返回0,否则返回非零值,此函数不会引起睡眠.
8 读写信号量
说明: 读写信号量与信号量的关系与读写锁与自旋锁的关系是一样的. 变量: rw_semaphore sem 函数: init_rwsem(&sem) down_read up_read down_read_trylock down_write up_write down_write_trylock 完成量 说明: 完成量是为了同步两个进程. 变量: completion comp; 函数: init_completion(&comp); DECLARE_COMPLETION(name) wait_for_completion complete complete_all 用法: 进程A 进程B wait_for_completion complete
10 互斥体
说明: 互斥体与信号量是一样的.变量: mutex mux;函数: mutex_init(&mux) mutex_lock mutex_unlock mutex_trylock mutex_lock_interruptible 用法: mutex_lock ... mutex_unlock
0 0
- Linux中的同步问题(Linux驱动1)
- Linux驱动编写中的问题
- linux中的线程同步:生产者、消费者问题
- Linux 设备驱动中的阻塞和同步机制
- Linux设备驱动中的异步通知与同步I/O
- linux设备驱动中的阻塞和同步机制
- Linux驱动:信号量同步测试
- Linux驱动:信号量同步测试
- [Linux驱动入门]并发同步
- Linux中的线程同步
- Linux中的同步机制
- Linux内核中的同步
- Linux中的同步机制
- Linux中的同步机制
- linux线程同步问题
- linux线程同步问题
- linux 线程同步问题
- Linux--时间同步问题
- No qualifying bean of type [services.ExportService] found for dependency问题原因
- Linux命令——网络命令
- 泛型(1)
- 1012. 数字分类
- 【c++】this指针的使用
- Linux中的同步问题(Linux驱动1)
- python: lambda, filter, map, reduce 用法
- 活动选择
- 常见的排序算法的复杂度问题
- 【C++】隐含的this指针
- memcached(十八)并发原语CAS与GETS操作
- Linux命令——关机重启命令
- Linux中mysql每天自动备份
- hdu 2197 本原串(数论+快速幂)