(1)自旋锁VS信号量
从严格意义上说,信号量和自旋锁属于不同层次的互斥手段,前者的实现依赖于后者。在信号量本身的实现上,为了保证信号量结构存取的原子性,在多CPU中需要自旋锁来互斥。
信号量是进程级别的,用于多个进程之间对资源互斥,虽然也是在内核中,但是该内核执行路径是以进程的身份,代表进程来竞争资源的。如果竞争失败,会发生进程上下文切换,当前进程进入睡眠状态,CPU将运行其他进程。鉴于进程上下文切换的开销也很大,因此,只有当进程占有资源时间较长时,用信号量才是较好的选择。
    当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它节省上下文切换的时间。但是CPU得不到自旋锁会在那里空转直到其他执行单元解锁为止,所以要求锁不能在临界区里长时间停留,否则会降低系统的效率。
    自旋锁会导致死循环,锁定期间不允许阻塞,因此要求锁定的临界区小。信号量允许临界区阻塞,可以使用于临界区大的情况。
 
(2)阻塞操作VS非阻塞操作
阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。而非阻塞操作的进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直至可以进行操作为止。
如果设备驱动不阻塞,则用户想获取设备资源只能不停的查询,这样会无谓的消耗CPU资源。而阻塞访问时,不能获取资源的进程将进入休眠,它将CPU资源让给其他进程。
在设备驱动中阻塞I/O一般基于等待队列来实现的,等待队列可用于同步驱动中时间发生的先后顺序。使用非阻塞I/O的应用程序也可借助轮询函数来查询设备是否能立即被访问,用户空间调用select()和poll()接口,设备驱动提供poll()函数。设备驱动的poll()本身不会阻塞,但是poll()和select()系统调用则会阻塞的等待文件描述符集合中的至少一个可访问或超时。
 
(3)向量中断VS非向量中断
据中断入口跳转方法的不同,中断分为向量中断和非向量中断。采用向量中断的CPU通常为不同的中断分配不同的中断号,当检测到某中断号的中断到来后,就自动跳转到与该中断号对应的地址执行。不同中断号的中断有不同的入口地址。非向量中断的多个中断共享一个入口地址,进入该入口地址后再通过软件判断中断标志来识别具体是哪个中断。也就是说,向量中断由硬件提供中断服务程序入口地址,非向量中断由软件提供中断服务程序入口地址。
硬中断是外部设备对CPU的中断,软中断通常是硬中断服务程序对内核的中断,而信号则是由内核(或其他进程)对某个进程的中断。