自旋锁、信号量、互斥锁的介绍和区别

本文转载自:http://blog.csdn.net/u012719256/article/details/52670098


信号量一般又叫做信号灯,协调不同进程间的数据对象的,本质上是一个计数器,记录对某个资源(共享内存)的存取情况。
从定义来看,信号量底层使用到了spin lock的锁定机制,这个spinlock主要用来确保对count成员的原子操作
使用的大致方式:
1)测试控制该资源的信号量
2)若此信号量为正,允许使用,进程将信号量-1
3)若信号量=0,则不可使用,进程进入睡眠状态,直到信号量大于0,进程被resume,jump to step1).
4)但进程不再使用一个信号量控制资源时,信号量+1,测试如果有进程正在等待此信号量,唤醒此进程。
解释:
信号量的获取:
( 1 ). void down( struct semaphore *sem); //废弃

在保证原子操作的前提下,先测试count是否大于0, ~ 如果是说明可以获得信号量,这种情况下需要先将count--,以确保别的进程能否获得该信号量,然后函数返回,其调用者开始进入临界区。 ~ 如果没有获得信号量,当前进程利用struct semaphore 中wait_list加入等待队列,开始睡眠。
( 2 ). int down_interruptible( struct semaphore *sem);

/* 试图去获得一个信号量,如果没有获得,函数立刻返回1而不会让当前进程进入睡眠状态。 */  
( 3 ). int down_trylock( struct semaphore *sem);

/* 如果没有其他线程等待在目前即将释放的信号量上,那么只需将count++即可。如果有其他线程正因为等待该信号量而睡眠,那么调用__up唤醒睡眠的进程*/  
void up( struct semaphore *sem);    //信号量的释放

互斥锁:
互斥主要现在了互相排斥(mutual exclusion)同步的简单形式,所以也叫mutex(互斥体)。
互斥体禁止多个线程同时进入受保护的代码临界区。因此,任何时刻,只有一个线程被允许进入这样的代码保护区
mutex实际上是count=1情况下的semaphore。而我们开发用的最多的锁就是mutex。

// 定义互斥锁lock
mutex_init( struct mutex* lock
// 获取
mutex_lock( struct mutex * lock )
// 释放
mutex_unlock( struct mutex * lock )

// 结构 struct mutex {  
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count; 
spinlock_t wait_lock;  
struct list_head wait_list;
#ifdef CONFIG_DEBUG_MUTEXES struct thread_info *owner;  
const char *name; void *magic;  
#endif  
#ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map;
#endif
};

自旋锁:
任何时刻,最多只能有一个保持者
区别于mutex:
对于mutex,如果资源已经被占用,资源的申请者只能进入suspend状态
但是自旋锁不会引起调用者suspend,如果自旋锁已经被别的单元持有,调用者会一直循环查看该锁是否释放(自旋的含义)
最大的区别,自旋锁不会suspend

结构:
# linux/Spinlock.h  
typedef struct spinlock { 
union { //联合  
struct raw_spinlock rlock;  
#ifdef CONFIG_DEBUG_LOCK_ALLOC  
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
struct { u8 __padding[LOCK_PADSIZE]; struct lockdep_map dep_map;
};
#endif  
};
} spinlock_t;

init:
spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
void spin_lock_init(spinlock_t * lock );

自旋锁和互斥锁的对比:
信号量量/互斥体 允许进程睡眠属于 睡眠锁 ,自旋锁则 不允许调用者睡眠 ,而是让其 循环等待 ,所以有以下区别应用  
1)、信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因而自旋锁适合于保持时间非常短的情况  
2)、 自旋锁可以用于中断,不能用于 进程上下文 (会引起死锁) 。而 信号量不允许使用在中断中,而可以用于进程上下文  
3)、自旋锁保持期间是抢占失效的,自旋锁被持有时,内核不能被抢占,而 信号量和读写信号量保持期间是可以被抢占的(意味着可以被中断)


使用场所:
信号量主要适用于进程间通信,当然,也可用于线程间通信。
而互斥锁只能用于线程间通信。

你可能感兴趣的:(System,Driver)