04clock

  1 内核的并发控制
  2 linux 内核中竞争发生的情况
  3 1.  进程与抢占它的进程
  4 2. 进程和中断
  5 3. smp  多处理器
  6 
  7 访问共享资源的代码区域一般称之为临界区,
  8 临界区需要被以某种互斥的机制加以保护
  9 
 10 上锁
 11 临界区
 12 解锁
 13 
 14 1.中断屏蔽
 15 local_irq_enable();  //使能中断
 16 local_irq_disable();  //屏蔽中断
 17 
 18 
 19 2.原子操作   atomic.h
 20 include/asm-generic/atomic.h
 21 保护变量
 22 类型:  atomic_t   v
 23 
 24 对于原子操作,所有v操作必须调用其中函数,才能达到原子操作目的
 25 atomic_t v = ATOMIC_INIT(0);   //初始化v 为0;
 26 atomic_read(v)   获取原子操作的值 
 27 
 28 static inline void atomic_add(int i, atomic_t *v)
 29 把原子操作v 加上i
 30 
 31 static inline void atomic_sub(int i, atomic_t *v)
 32 v  减 i
 33 
 34 static inline void atomic_inc(atomic_t *v)  自增
 35 static inline void atomic_dec(atomic_t *v)  自减
 36 
 37 atomic_dec_and_test  自减 和 0比较
 38 
 39 3.自旋锁
 40 spinlock.h
 41 当获取不了资源时候,CPU会在原地打转
 42 spinlock_t      lock定义自旋锁
 43 spin_lock_init(&lock)    自旋锁的初始化
 44 spin_lock(&lock)  上锁
 45 
 46 spin_unlock(&lock)  解锁
 47 
 48 spin_trylock(&lock)  该函数立即返回
 49 如果获取成功返回非0      失败返回0
 50 
 51 
 52 
 53 读写自旋锁 rwlock.h
 54 当访问一块共享区域,读的操作并不会影响到共享区域,所以读和读之间没有必要互斥
 55 
 56 读和读     不互斥
 57 写和写     互斥
 58 读和写     互斥
 59 
 60 前提:  临界区 一定要严格区分 读和写
 61 
 62 rwlock_t   读写自旋锁的类型
 63 
 64 rwlock_init(&lock)  初始化
 65 
 66  67 read_lock(&lock)    上读锁
 68 read_unlock(&lock)  解读锁
 69 
 70  71 write_lock(&lock)   上写锁
 72 write_unlock(&lock)   解写锁
 73 
 74 读锁和写锁  必须指向同一个 lock
 75 
 76 顺序锁
 77 seqlock_t  类型
 78 针对 读写锁一个改进,在读写锁基础上,让读和写 不再互斥
 79 这种锁 适用如下场景:
 80 1.能够严格区分 读 和 写 
 81 2.  读的操作要远大于写操作,反之有可能会造成死锁
 82 
 83 seqlock_init(&lock);   读写的初始化
 84 
 85 write_seqlock(&lock)   上写锁
 86 xxxxx
 87 write_unseqlock(&lock)   解写锁
 88 
 89 
 90 读锁
 91 read_seqbegin();  
 92 read_seqretry();
 93 do {
 94     seq = read_seqbegin(&lock);
 95     xxxxxx;  临界区
 96 }while(read_seqretry(&lock, seq))
 97 
 98 
 99 
100 
101 4.信号量
102 semaphore.h
103 信号量会引发进程间的调度
104 
105 semaphore  ;
106 sema_init(&sema, 1);   //初始化为1  用于互斥
107 
108 down(&sem)    获取信号量
109 down_trylock(&sema);   立即返回,无论有没有获得锁,
110 
111 up(&sem)    释放信号量
112 
113 
114 读写信号量   同读写自旋锁
115 rwsem.h
116 rw_semaphore  类型
117 init_rwsem(&rwsem)   初始化
118 
119 down_read(&rwsem)  上读锁
120 up_read(&rwsem)    解读锁
121 
122 down_write(&rwsem)  上写锁
123 up_write(&rwsem)   解写锁
124 
125 总结:   
126 1.关闭中断尽量不要用
127 2.原子操作针对是变量,自旋锁和信号量保护代码段
128 3.由于信号量会引发进程间的调度,进程间切换是需要消耗事件,
129 所以如果保护代码段比较小,适合用自旋锁,如果保护的代码段比较大,
130 适合用信号量.
131 4.自旋锁是忙等,不会引发进程的切换,如果中断需要互斥,用spinlock
132 spinlock_trylock
133 5.会引起阻塞的代码段,不要用spinlock,用信号量
134 
135 
136 互斥体
137 简化版的信号量    信号量值为1,简化版
138 
139 mutex
140 
141 mutex_init(&mutex)     //初始化信号量
142 mutex_lock(&mutex)    上锁
143 mutex_unlock(&mutex)  解锁

 

posted @ 2017-02-19 16:51  小黑·.·  阅读(237)  评论(0编辑  收藏  举报