这可能看起来有点荒谬,但我很困惑。
- 锁定和阻塞操作之间到底有什么区别?
- 我们什么时候使用 Block,什么时候使用 Lock?
- 当我们可以使用自旋锁、信号量等使调用进程进入睡眠状态时(我想它会发生,如果我错了请指出)那么我们为什么要创建 wait_queues 来让进程进入睡眠状态(我希望这是阻塞)。
请回答。
这可能看起来有点荒谬,但我很困惑。
请回答。
当我们可以使用自旋锁、信号量等使调用进程进入睡眠状态时(我想它会发生,如果我错了请指出)
这是错误的,当您使用自旋锁、信号量等时,您并没有让进程进入睡眠状态。在自旋锁的情况下,如果您在获得自旋锁时睡觉是很危险的。
为了避免并发访问,锁定是必要的。假设您正在编写打印机驱动程序。驱动程序接收来自应用程序的文本,并将文本打印在纸上。如果您有两个需要同时打印的应用程序怎么办?如果您不使用锁定策略,您将在同一页面上阅读来自两个不同应用程序的混合文本。例如,在这种情况下,您可以使用信号量或互斥体。当第一个应用程序访问驱动程序时,驱动程序获取互斥锁(信号量),直到应用程序完成发送文本。当第二个应用程序访问驱动程序时,驱动程序无法继续,因为另一个进程使互斥锁处于活动状态。因此,第二个打印过程可以休眠,直到第一个打印结束。当第一个打印进程释放互斥体时,第二个进程开始打印。
您的用户空间应用程序可以使用阻塞或非阻塞方法(man open(2))。当驱动程序忙于第一个打印进程而发生第二个打印进程时,根据应用程序的选择,驱动程序可以阻塞第二个进程,或者立即返回。如果它是阻塞的,驱动程序将使用一个 wait_queues 让进程进入睡眠状态,直到有人会唤醒(当它结束时的第一个进程)。如果是非阻塞的,驱动程序返回一个错误码(例如:EBUSY,EAGAIN),控制返回应用程序;现在应用程序可以决定稍后重试、休眠一段时间或放弃打印并将控制权返回给用户
自旋锁用于低级并发。例如,不同进程同时使用的变量。在这种情况下,我们必须保证两个不同的处理器不会同时写入同一个变量,因为结果是不可预测的。因此,我们将对变量执行以下操作来保护
[get the spin lock]
[chage the variable(s)]
[release the spin lock]
这保证了一次只有一个进程会修改受自旋锁保护的变量。在睡眠时使用自旋锁是危险的,因为自旋锁不睡眠。当一个进程发现一个活动的自旋锁时,它不会休眠,而是在一个while循环中等待,直到有人释放自旋锁。如果您使用活动的自旋锁睡觉,那么会有其他人因此无法入睡。
无论如何,这是一个有用的链接LDD3 Chapter 5。