内核中用于临界区保护下的互斥机制,它包括自旋锁、原子操作和信号量,三者保证了对临界资源访问的互斥型。
1.1 内核中的互斥机制
1.1.1 自旋锁
自旋锁用在多个CPU系统中。当一个线程在一个CPU上正使用资源,而另一个线程在另一个CPU上正忙等待这个资源的时候,就会用到自旋锁来保护临界资源。在单处理器系统中,自旋锁函数扩展为空。
自旋锁基于共享变量。函数通过给变量设置一个值来获得锁,其他需要锁的函数就会查询它,并知道锁现在不可用,然后在一个忙等待的循环中“自旋”,直到锁可用为止。
由于使用自旋锁时,其他CPU被强制等待。因此持有自旋锁的函数不能花费过长时间。
下面说明操作自旋锁的宏:
- spin_loc(spinlock_t *lock):获得给定的锁,直到锁成为可用状态为止。在spin_lock返回之后,调用函数将拥有该锁。
- spin_lock_irq(spinlock_t *lock):类似spin_lock_irqsave,只是不保存当前的中断状态。
- spin_lock_bh(spinlock_t *lock):获得给定的锁并且阻止底半部的执行。
- spin_unlock(spinlock_t *lock):此宏开锁,它与前面加锁的宏是配对使用的。spin_unlock解开给定的锁而不做其他的工作。
- spin_unlock_irq(spinlock_t *lock):此宏开锁,它与前面加锁的宏是配对使用的。spin_unlock_irq无条件地启动中断。
- spin_unlock_bh(spinlock_t *lock):此宏开锁,它与前面加锁的宏是配对使用的。spin_unlock_bh重新启动底半部处理。
linux还有另外一种类型的自旋锁,称为“读者/写者自旋锁”。读者/写者问题,即如果有多个线程(进程、中断处理程序、底半部例程)需要以只读的方式访问一个临界区数据,众多的读者之间不会彼此干预,而只有写者之间会产生竞争。
1.2 原子操作
原子操作指某些操作的执行不可中断。原子操作分为bitops和atomic_两类。在原子操作中,常遇到声明volatile。将变量声明为volatile时,系统会阻止编译器对给值进行优化,确保变量使用了用户定义的精确地址,而不是装有同一信息的一些别名。
bitops原子操作方式是在一些标志的设置需要进行原子操作的情况下使用的。原子的位操作是非常快的,使用单条机器指令来完成操作。
atomic_t原子操作方式用于加减之类的运算,这个操作是原子性的,它用单条机器指令来完成操作。
1.3 信号量
进程间对共享资源的互斥访问是通过信号量机制来实现的。内核中提供了函数down和函数up对信号量进行操作。
信号量和自旋锁有一定的区别,用信号量的down操作如果无法得到资源,那就会进入等待队列,通过调度去运行其他进程。而在自旋锁中,如果无法得到资源,将进入忙等待,直到得到资源。因此,如果资源被占用时间很短,则使用自旋锁较好,因为它可节约调度时间。如果资源被占用的时间较长,使用信号量较好,因为可让CPU调度去做其他进程的工作。
信号量的实现包括信号量的初始化及函数up和函数down的实现。
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html