linux设备驱动--并发与竞态之自旋锁

来源:互联网 发布:淘宝上怎么搜买家 编辑:程序博客网 时间:2024/05/16 19:45

        自旋锁(spin lock)是一种典型的对临界资源进行互斥访问的手段。与信号量不同,自旋锁可在不能休眠的代码中使用,比如中断处理例程。(自旋锁api的一些衍生都是与中断相关的)在正确使用的情况下,自旋锁通常可以提供比信号量更高的性能。

        自旋锁相关的主要操作如下:

This initialization may be done at compile time as follows:spinlock_t my_lock = SPIN_LOCK_UNLOCKED;or at runtime with:void spin_lock_init(spinlock_t *lock);Before entering a critical section, your code must obtain the requisite lock with:void spin_lock(spinlock_t *lock);Note that all spinlockwaits are, by their nature, uninterruptible. Once you callspin_lock, you will spin until the lock becomes available.To release a lock that you have obtained, pass it to:void spin_unlock(spinlock_t *lock);

       自旋锁使用时注意的几个问题:

        1、自旋锁必须在可能的最短时间内拥有。因为自旋锁实际上是忙等锁,cpu在等待自旋锁时是不做任何有用的工作的,仅仅是等待。当临界区很大,或有共享设备的时候,需要较长时间占用锁,使用自旋锁会降低系统的性能。

        2、小心处理防止系统死锁。最常见的一个情况是多次使用一个自旋锁。这个和多线程中的死锁在概念上比较类似。

        3、自旋锁锁定期间不能调用可能引起进程调度的函数。如果进程获得自旋锁之后再阻塞,如copy_from_user()、copy_to_user()、kmalloc()等宏定义或函数,则可能会导致内核的崩溃。


        内核还提供自旋锁的读取/写入形式,这就是读写锁。这种锁允许任意数量的读取者同时进入临界区,但写入者必须互斥访问。在多线程中,也提供一种读写锁。二者的概念比较类似。

       在使用锁时有一条锁的顺序规则:

        在获取多个锁时,应始终以相同的顺序获得。最好是避免出现需要多个锁的情况.

       

        因为在scull的例子中是操作内存的,所以会存在copy_to_user()和copy_from_user()这些可能导致阻塞的函数,所以不宜使用自旋锁。在今后的学习工作中,遇到驱动代码中有使用自旋锁的场景时再回头温习一个spin lock,做到理论联系实际~~