【发布时间】:2021-06-12 01:57:00
【问题描述】:
一本书展示了一个简单的等待锁
class SimpleWaitLock : IDisposable {
private readonly AutoResetEvent m_available;
public SimpleWaitLock() {
m_available = new AutoResetEvent(true); // Initially free
}
public void Enter() {
// Block in kernel until resource available
m_available.WaitOne();
}
public void Leave() {
// Let another thread access the resource
m_available.Set();
}
public void Dispose() {
m_available.Dispose();
}
}
然后说:
自动重置事件的行为与最大计数为 1 的信号量非常相似,并且 Set 可以在 自动重置事件,仍然只有一个线程会被解锁
我有点困惑,假设我们调用了两次 Set 方法:
class SimpleWaitLock : IDisposable {
...
public void Enter() {
m_available.WaitOne();
}
public void Leave() {
m_available.Set();
m_available.Set();
}
}
假设我们有三个线程A、线程B和线程C,线程A持有锁,线程B和线程C阻塞。当threadA释放资源(第一次m_available.Set();)调用时,内核对象被发出一次信号,因此threadB获得了锁(内核对象被发出“正在使用”的信号),所以ThreadC仍然处于阻塞状态。
但是现在threadA调用了 m_available.Set();的第二次调用,所以内核对象再次被信号为空闲(未使用),那么它不是要解锁threadC,所以threadB和threadC现在可能同时运行?如果我的理解是正确的,为什么书上说只发布一个线程?
【问题讨论】: