注意在waitforsingleobject之后又重新进入临界区,但没有做任何事就退出了,似乎没有意义,但这是必须的!
因为临界区的enter和leave必须严格的一一对应。那么是否可以改成这样呢:
if assigned(wakemainthread) then
wakemainthread(syncproc.syncrec.fthread);
waitforsingleobject(syncproc.signal, infinite);
finally
leavecriticalsection(threadlock);
end;
上面的代码和原来的代码最大的区别在于把waitforsingleobject也纳入临界区的限制中了。看上去没什么影响,还使代码大大简化了,但真的可以吗?
事实上是不行!
因为我们知道,在enter临界区后,如果别的线程要再进入,则会被挂起。而waitfor方法则会挂起当前线程,直到等待别的线程setevent后才会被唤醒。如果改成上面那样的代码的话,如果那个setevent的线程也需要进入临界区的话,死锁(deadlock)就发生了(关于死锁的理论,请自行参考操作系统原理方面的资料)。
死锁是线程同步中最需要注意的方面之一!