我有一个简单的生产者/消费者场景,其中只有一件产品正在生产/消费。此外,生产者在继续之前等待工作线程完成。我知道那种避免了多线程的整点,但请你只认为它真正需要的是这样的(:Monitor.Wait/Pulse的这种用法是否具有竞争条件?
此代码不能编译,但我希望你的想法:
// m_data is initially null
// This could be called by any number of producer threads simultaneously
void SetData(object foo)
{
lock(x) // Line A
{
assert(m_data == null);
m_data = foo;
Monitor.Pulse(x) // Line B
while(m_data != null)
Monitor.Wait(x) // Line C
}
}
// This is only ever called by a single worker thread
void UseData()
{
lock(x) // Line D
{
while(m_data == null)
Monitor.Wait(x) // Line E
// here, do something with m_data
m_data = null;
Monitor.Pulse(x) // Line F
}
}
这里是我不知道的情况:
假设多线程调用的SetData()与不同的输入 只有其中一人将获得锁内,其余的将被封锁(A线) 假设里面锁套的那个m_data并且进入C线。
问题:线C上的Wait()是否允许线A上的另一个线程获取该锁并在工作线程甚至达到它之前覆盖m_data?
假设没有发生,并且工作线程处理原始的m_data,并且最终到达F行,那么当Pulse()熄灭时会发生什么?
只有线C上等待的线程能够获得锁吗?或者它会与在线A上等待的所有其他线程竞争吗?本质上,我想知道Pulse()/ Wait()是否特别相互“沟通”,或者它们与lock()处于同一级别。
这些问题的解决方案(如果存在的话)当然是显而易见的 - 只需将SetData()与另一个锁 - 比如lock(y)包围即可。 我只是好奇,如果它甚至是一个问题开始。