У меня есть несколько потоков, которые используют семафор. Thread A удерживает семафор (с помощью блокировки), а потоки B и C ждут того же семафора (также используя блокировку). Потоки разделяют глобальные переменные и т. Д..NET Concurrency Вопрос: могу ли я предоставить семафор другому потоку
Есть ли способ в C#, который я могу использовать для закрытия потока B? Я могу установить флаг в A и иметь поток B проверить этот флаг и выйти, как только он получит контроль над семафором, но я не знаю какой-либо техники, чтобы поток A мог дать семафор потоку B (и получить его назад, когда нить B выходит), без риска контроля резьбы C.
У кого-нибудь есть предложения по решению этой проблемы с дизайном? Я могу переписать программу по мере необходимости, если я приближаюсь к ней неправильно.
[Редактировать] Комментатор указал, что я использую неправильную терминологию. Комментарий правильный: я использую критический раздел, но учитывая, что все работает в одном процессе, в этом примере критические разделы функционально эквивалентны более общему термину «семафор».
[Изменить] Кто-то попросил более подробную информацию, так что вот оно.
Там может быть несколько потоков выполнения кода A. Там только когда один поток выполнения кода B.
Код A:
private static Thread workerThread = null;
lock (lockObject)
{
... do some work ...
if (...condition...)
{
if (workerThread != null)
{
// Kill the worker thread and continue only after it is dead.
quitWorkerThread = true;
// Wait for the thread to die.
while (workerThread.IsAlive)
{
Thread.Sleep(50);
}
workerThread = null;
quitWorkerThread = false;
} // if (workerThread != null)
} // if (...condition...)
... do some more work ...
if (...condition...)
{
if (workerThread == null)
{
// Start the worker thread.
workerThread = new Thread(WorkerThread);
workerThread.Start();
} // if (workerThread == null)
} // if (...condition...)
... do even more work ...
} // lock (lockObject)
Код B:
private void WorkerThread()
{
while (true)
{
if (quitWorkerThread)
{
return;
}
Thread.Sleep (2000);
if (quitWorkerThread)
{
return;
}
lock(lockObject)
{
if (quitWorkerThread)
{
return;
}
... do some work ...
} // lock(lockObject)
} // while (true)
} // WorkerThread
Я подозреваю, что вариант решения Аарона будет тем, что я использую. В основном я надеялся, что было несколько более элегантное решение, но я подозреваю, что, как и все остальное в этом проекте, это все грубые силы и угловые случаи :-(.
«Резьба A содержит семафор (с использованием блокировки)» - инструкция 'lock' является критическим разделом. Используете ли вы семафоры или критические разделы (блокировку)? – Aaronaught
Если вы используете семафоры, вы, вероятно, будете использовать waitOne(). – Zach
FYI, критический раздел сильно отличается от семафора даже в рамках одного процесса. Критический раздел позволяет точно * одному * потоку удерживать ресурс; семафор может допускать несколько. Семантика блокировки также различна; поток может повторно вводить свой критический раздел сколько угодно раз, но семафоры не заботятся о идентичности потоков, поэтому повторное получение его слишком много раз будет заторможено. Извините за педантизм, но различие очень важно. – Aaronaught