In the linux kernel, why can't you sleep while holding a spinlock?
相关问题
- Is shmid returned by shmget() unique across proces
- how to get running process information in java?
- Error building gcc 4.8.3 from source: libstdc++.so
- Why should we check WIFEXITED after wait in order
- Null-terminated string, opening file for reading
The key point is in Linux kernel, acquiring a spin lock will disable preemption. Thus sleeping while holding a spin lock could potentially cause deadlock.
For example, thread A acquires a spin lock. Thread A will not be preempted until it releases the lock. As long as thread A quickly does its job and releases the lock, there is no problem. But if thread A sleeps while holding the lock, thread B could be scheduled to run since the sleep function will invoke the scheduler. And thread B could acquire the same lock as well. Thread B also disables preemption and tries to acquire the lock. And a deadlock occurs. Thread B will never get the lock since thread A holds it, and thread A will never get to run since thread B disables preemption.
And why disabling preemption in the first place? I guess it's because we don't want threads on other processors to wait too long.
I disagree with William's response (his example). He's mixing two different concepts: preemption and synchronization.
An Interrupt Context could preempt a Process Context and thus if there a RESOURCE shared by the both, we need to use
to (1) disable the IRQ (2) acquire the lock. By step 1, we could disable interrupt preemption.
I think this thread is much convincing. Sleep() means a thread/process yields the control of the CPU and CONTEXT SWITCH to another, without releasing the spinlock, that's why it's wrong.