我有一個簡單的生產者/消費者場景,其中只有一件產品正在生產/消費。此外,生產者在繼續之前等待工作線程完成。我知道那種避免了多線程的整點,但請你只認爲它真正需要的是這樣的(: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)包圍即可。 我只是好奇,如果它甚至是一個問題開始。