作用:避免竞争
一. 自旋锁
使用步骤:
1.定义自旋锁
spinklock_t lock;
2.初始化自旋锁
spin_lock_init(&lock);
3.获得自旋锁
spin_lock(&lock);
4.释放自旋锁
spin_unlock(&lock);
spin_lock [如果获得lock则立即返回,否则将自旋在那里直到其他线程释放]
临界资源
spin_unlock
二.信号量
struct semaphore{
spinlock_t lock;
unsigned int count;
struct list_head wait_list;
}
lock主要是对count起保护作用,当count值需要修改时,lock锁住,修改完释放lock
count值
0:有进程正在使用,不可使用,wait_list 0进程在等待
<0 : 不可用,wait_list中至少有一个进程在等待
>0 : 信号量空闲,可使用
定义和初始化信号量
struct semaphore sema;
static inline void sema_init(struct semaphore *sem,int val)
定义为mutex互斥量
#define init_MUTEX(sem) sema_init(sem,1)
#define init_MUTEX_LOCKED(sem) sema_init(sem,0)
获取信号量
void down(struct semaphore *sem) 该函数会休眠,不能在中断中使用
void down_interruptible(struct semaphore *sem) 休眠可唤醒
释放信号量
void up(struct semaphore *sem)
同步使用:
线程A:
semaphore sem;
在open中
init_MUTEX_LOCKED(&sem)
down(&sem) ---进入休眠,等待唤醒
被保护的代码A
线程B中:
被保护代码B
在release 中:
up(&sem)释放信号量 ---可唤醒进程A
上面的例子保证了被保护的代码B执行之后被保护的代码A才执行
如果 init_MUTEX(sem) 可保证两个线程只有其中一个运行
三.自旋锁和信号量的区别
自旋锁:忙等待,占用时间比较短时候使用
信号量:休眠,需要上下文切换,耗时,占用时间比较长时候使用
注意:不能在中断中休眠!