Имеет ли такое использование Monitor.Wait/Pulse состояние гонки?C#

Место общения программистов C#
Ответить
Anonymous
 Имеет ли такое использование Monitor.Wait/Pulse состояние гонки?

Сообщение Anonymous »

У меня есть простой сценарий производитель/потребитель, в котором производится/потребляется только один элемент. Кроме того, перед продолжением производитель ждет завершения рабочего потока. Я понимаю, что это устраняет весь смысл многопоточности, но, пожалуйста, предположите, что так и должно быть (:

Этот код не компилируется, но я надеюсь, что вы поняли идею:

Код: Выделить всё

// 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.

Вопрос: может ли функция Wait() в строке C позволить другому потоку в строке A получить блокировку и перезаписать m_data еще до того, как рабочий поток доберется до нее?

Предположим, что этого не происходит, и рабочий поток обрабатывает исходные m_data и в конечном итоге достигает строки F, что произойдет, когда сработает Pulse()?

Будет только поток, ожидающий в строке C, сможет получить блокировку? Или он тоже будет конкурировать со всеми остальными потоками, ожидающими на линии A?

По сути, я хочу знать, взаимодействуют ли Pulse()/Wait() друг с другом специально «под капотом» или они находятся на одном уровне с lock().

Решение этих проблем, если они существуют, конечно, очевидно — просто окружите SetData() другой блокировкой — скажем, lock(y).
Мне просто интересно, является ли это вообще проблемой.

Подробнее здесь: https://stackoverflow.com/questions/263 ... -condition
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»