自旋锁
不能睡眠,持有时间尽可能短
linux/spinlock.h spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
void spin_lock_init(spinlock_t *lock); //动态初始化
void spin_lock(spinlock_t *lock); void spin_lock_irqsave(spinlock_t *lock, unsigned long flags); void spin_lock_irq(spinlock_t *lock); void spin_lock_bh(spinlock_t *lock) //spin_lock 禁止中断 //spin_loc_irqsave 禁止中断(只在本地处理器)在获得自旋锁之前; 之前的中断状态保存在 flags 里 //spin_lock_irq 确信释放你的自旋锁时打开中断 //spin_lock_bh 在获取锁之前禁止软件中断, 但是硬件中断是打开的
void spin_unlock(spinlock_t *lock); void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags); void spin_unlock_irq(spinlock_t *lock); void spin_unlock_bh(spinlock_t *lock);
int spin_trylock(spinlock_t *lock); int spin_trylock_bh(spinlock_t *lock); //非阻塞的自旋锁操作,函数成功时返回非零( 获得了锁 ), 否则 0
读者/写者自旋锁 linux/spinlokc.h
rwlock_t my_rwlock = RW_LOCK_UNLOCKED; /* Static way */ rwlock_t my_rwlock; rwlock_init(&my_rwlock); /* Dynamic way */
可用函数的列表现在应当看来相当类似. 对于读者, 下列函数是可用的:
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);
void read_unlock(rwlock_t *lock); void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags); void read_unlock_irq(rwlock_t *lock); void read_unlock_bh(rwlock_t *lock);
有趣地, 没有 read_trylock. 对于写存取的函数是类似的:
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);
void write_unlock(rwlock_t *lock); void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags); void write_unlock_irq(rwlock_t *lock); void write_unlock_bh(rwlock_t *lock);
|
不加锁算法
在内核中通用的环形缓存linux/kfifo.h
原子变量
asm/atomic.h atomic_t v = ATOMIC_INIT(0); //编译时 void atomic_set(atomic_t *v, int i); //动态设定 int atomic_read(atomic_t *v); //返回 v 的当前值. void atomic_add(int i, atomic_t *v); //由 v 指向的原子变量加 i. 返回值是 void void atomic_sub(int i, atomic_t *v); //从 *v 减去 i.
void atomic_inc(atomic_t *v); void atomic_dec(atomic_t *v); //递增或递减一个原子变量.
int atomic_inc_and_test(atomic_t *v); int atomic_dec_and_test(atomic_t *v); int atomic_sub_and_test(int i, atomic_t *v); //进行一个特定的操作并且测试结果; 如果, 在操作后, 原子值是 0, 那么返回值是真; 否则, 它是假. 注
意没有 atomic_add_and_test.
int atomic_add_negative(int i, atomic_t *v); //加整数变量 i 到 v. 如果结果是负值返回值是真, 否则为假.
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); //就像 atomic_add 和其类似函数, 除了它们返回原子变量的新值给调用者.
|
注意:
需要多个 atomic_t 变量的操作仍然需要某种其他种类的加锁.
atomic_t 假设最多24 位,不要赋的值太大
位操作
asm/bitops.h void set_bit(nr, void *addr); //设置第 nr 位在 addr 指向的数据项中. void clear_bit(nr, void *addr); //清除指定位在 addr 处的无符号长型数据. 它的语义与 set_bit 的相反. void change_bit(nr, void *addr); //翻转这个位. test_bit(nr, void *addr); // 返回这个位的当前值.
int test_and_set_bit(nr, void *addr); int test_and_clear_bit(nr, void *addr); int test_and_change_bit(nr, void *addr); //原子地动作如同前面列出的,还返回这个位以前的值.
|
seqlock 锁
读取-拷贝-更新
阅读(1189) | 评论(0) | 转发(0) |