莫小帅|kernel同步机制(上篇),Linux( 二 )


而owner的值由arch_spin_unlock控制 , 即unlock控制何时结束等待 。
Spin_lockbasicAPI
安全上 , spin_lock_irqsave>spin_lock_irq>spin_lock_bh>spin_lock 。
Spin_lock不同版本的使用
spin_lock用于阻止在不同CPU上的执行单元对共享资源的同时访问以及不同进程上下文互相抢占导致的对共享资源的非同步访问 , 而中断失效(spin_lock_irq)和软中断失效(spin_lock_bh)却是为了阻止在同一CPU上软中断或中断对共享资源的非同步访问 。
如果被保护的共享资源只在进程上下文访问和软中断上下文访问 , 那么当在进程上下文访问共享资源时 , 可能被软中断打断 , 从而可能进入软中断上下文来对被保护的共享资源访问 , 因此对于这种情况 , 对共享资源的访问最好使用spin_lock_bh和spin_unlock_bh来保护 。 如果被保护的共享资源只在进程上下文和tasklet或timer上下文访问 , 那么应该使用与上面情况相同 , 因为tasklet和timer是用软中断实现的 。 如果被保护的共享资源只在两个或多个tasklet或timer上下文访问 , 那么对共享资源的访问仅需要用spin_lock和spin_unlock来保护 , 不必使用_bh版本 , 因为当tasklet或timer运行时 , 不可能有其他tasklet或timer在当前CPU上运行 。 如果被保护的共享资源只在一个软中断(tasklet和timer除外)上下文访问 , 那么这个共享资源需要用spin_lock和spin_unlock来保护 , 因为同样的软中断可以同时在不同的CPU上运行 。 如果被保护的共享资源在软中断(包括tasklet和timer)或进程上下文和硬中断上下文访问 , 那么在软中断或进程上下文访问期间 , 可能被硬中断打断 , 从而进入硬中断上下文对共享资源进行访问 , 因此 , 在进程或软中断上下文需要使用spin_lock_irq和spin_unlock_irq来保护对共享资源的访问 。 在使用spin_lock_irq和spin_unlock_irq的情况下 , 完全可以用spin_lock_irqsave和spin_unlock_irqrestore取代 , 那具体应该使用哪一个也需要依情况而定 , 如果可以确信在对共享资源访问前中断是使能的 , 那么使用spin_lock_irq更好一些 , 因为它比spin_lock_irqsave要快一些 。 三、信号量(Semaphore)Linux内核的信号量在概念和原理上与用户态的SystemV的IPC机制信号量是一样的 , 但是它不可能在内核之外使用 , 因此它与SystemV的IPC机制信号量完全不同 。
信号量是这样一种同步机制:信号量在创建时设置一个初始值count , 用于表示当前可用的资源数 。 一个任务要想访问共享资源 , 首先必须得到信号量 , 获取信号量的操作为count-1 , 若当前count为负数 , 表明无法获得信号量 , 该任务必须挂起在该信号量的等待队列等待;若当前count为非负数 , 表示可获得信号量 , 因而可立刻访问被该信号量保护的共享资源 。 当任务访问完被信号量保护的共享资源后 , 必须释放信号量 , 释放信号量通过把count+1实现 , 如果count为非正数 , 表明有任务等待 , 它也唤醒所有等待该信号量的任务 。
StructureDefinition