互斥机制:
1、屏蔽中断
2、原子操作
定义原子变量 atomic_t v;
初始化 atomic_t v = ATOMIC_INIT(0);
操作
atomic_t v = ATOMIC_INIT(1);
open
{
if(atomic_dec_and_test(&v)) {
return 0
} else {
atomic_inc(&v);
return -EBUSY;
}
}
release
{
atomic_inc(&v);
}
自旋锁使用:
自旋锁是忙锁:系统开销较大,为了减小系统开销,需要减少等待时间而减少等到时间的唯一方法就是让持有锁的进程尽快释放锁,
而想要尽快释放锁,临界区代码要短小(执行时间短)
可以用在中断上下文中
通过关抢占实现:临界区代码中不能有可能引起睡眠的操作
定义 spinlock_t lock;
初始化 spin_lock_init(spinlock_t *);
spin_lock_init(&lock);
加锁 spin_lock(spinlock_t *);
spin_lock(&lock);
解锁 spin_unlock(spinlock_t *);
spin_unlock(&lock);
自旋锁实现访问控制:
spinlock_t lock;
spin_lock_init(&lock);---->加载函数
int flag = 1;
open
{
spin_lock(&lock);
if (flag == 1) {
flag--;
spin_unlock(&lock);
return 0;
} else {
spin_unlock(&lock);
return -EBUSY;
}
}
release
{
spin_lock(&lock);
flags++;
spin_unlock(&lock);
return 0;
}
对比
信号量 自旋锁
睡眠 忙
临界区可以很大 临界区要小
临界区可以有可能引起睡眠的操作 不能有可能引起睡眠的操作
(但尽量避免睡眠引起的死锁)
不能用在中断上下文中 可以用在中断上下文中
信号量的使用:
1、定义信号量
struct semaphore sema;
2、初始化
sema_init(struct semaphore *sema, int val);
sema_init(&sema, 1);
3、P操作
down(struct semaphore *sema);
down_interruptible(struct semaphore *sema);
down_trylock(struct semaphore *sema);
4、V操作
up(struct semaphre *sema);
struct semaphore sema;
sema_init(&sema, 1); ----> 加载函数
open
{
if(down_trylock(&sema))
return -EBUSY;
return 0;
}
release
{
up(&sema);
}
原子操作
顺序锁
信号量的使用:
down_interruptible(struct semaphore *sema) ;
当被其他信号唤醒的时候返回
1、屏蔽中断
2、原子操作
定义原子变量 atomic_t v;
初始化 atomic_t v = ATOMIC_INIT(0);
操作
atomic_t v = ATOMIC_INIT(1);
open
{
if(atomic_dec_and_test(&v)) {
return 0
} else {
atomic_inc(&v);
return -EBUSY;
}
}
release
{
atomic_inc(&v);
}
自旋锁使用:
自旋锁是忙锁:系统开销较大,为了减小系统开销,需要减少等待时间而减少等到时间的唯一方法就是让持有锁的进程尽快释放锁,
而想要尽快释放锁,临界区代码要短小(执行时间短)
可以用在中断上下文中
通过关抢占实现:临界区代码中不能有可能引起睡眠的操作
定义 spinlock_t lock;
初始化 spin_lock_init(spinlock_t *);
spin_lock_init(&lock);
加锁 spin_lock(spinlock_t *);
spin_lock(&lock);
解锁 spin_unlock(spinlock_t *);
spin_unlock(&lock);
自旋锁实现访问控制:
spinlock_t lock;
spin_lock_init(&lock);---->加载函数
int flag = 1;
open
{
spin_lock(&lock);
if (flag == 1) {
flag--;
spin_unlock(&lock);
return 0;
} else {
spin_unlock(&lock);
return -EBUSY;
}
}
release
{
spin_lock(&lock);
flags++;
spin_unlock(&lock);
return 0;
}
对比
信号量 自旋锁
睡眠 忙
临界区可以很大 临界区要小
临界区可以有可能引起睡眠的操作 不能有可能引起睡眠的操作
(但尽量避免睡眠引起的死锁)
不能用在中断上下文中 可以用在中断上下文中
信号量的使用:
1、定义信号量
struct semaphore sema;
2、初始化
sema_init(struct semaphore *sema, int val);
sema_init(&sema, 1);
3、P操作
down(struct semaphore *sema);
down_interruptible(struct semaphore *sema);
down_trylock(struct semaphore *sema);
4、V操作
up(struct semaphre *sema);
struct semaphore sema;
sema_init(&sema, 1); ----> 加载函数
open
{
if(down_trylock(&sema))
return -EBUSY;
return 0;
}
release
{
up(&sema);
}
原子操作
原子操作(cont)
自旋锁
自旋锁(cont)(防止中断的影响)
读写锁
读写锁(cont.)
顺序锁(cont)
down_interruptible(struct semaphore *sema) ;
当被其他信号唤醒的时候返回
retrun -ERESTARTSYS;
互斥体