Вложенные семафоры, безопасность и тупик - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть класс, использующий SemaphoreSlim, который вызывает другой класс, используя SemaphoreSlim. Он работает без тупика или состояния гонки.

Каково общее руководство по этому вопросу?

try
{
    await _semaphoreSlim.WaitAsync();
    DoWork();
}
catch (Exception e)
{

}
finally
{
    _semaphoreSlim.Release();   
}

private void DoWork(){
try
{
    await _semaphoreSlim2.WaitAsync();
    //more work
}
catch (Exception e)
{

}
finally
{
    _semaphoreSlim2.Release();  
}

}

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Вы также должны убедиться, что блокировки всегда получаются в одном и том же порядке, поэтому, если кто-то другой может вызвать DoWork, и что-то внутри DoWork может в конечном итоге вызвать ваш верхний блок кода, то у вас есть обратный порядок и вероятность тупиковой блокировки. ,

0 голосов
/ 27 апреля 2020

В этом случае вы используете SemaphoreSlim в качестве своего рода примитива "мьютекса" ("взаимное исключение").

Каждый мьютекс должен использоваться для защиты определенного c набора данные. Поэтому целесообразно использовать разные мьютексы для разных наборов данных. Как правило, мелкозернистые мьютексы лучше, чем крупнозернистые мьютексы.

Когда вы имеете дело с несколькими мьютексами, вы всегда должны убедиться, что они получены в одном и том же порядке. В вашем примере есть код, который содержит _semaphoreSlim, затем вызывается код, который получает _semaphoreSlim2. Это хорошо, но вы должны документировать это, потому что вы никогда не хотите, чтобы код, содержащий _semaphoreSlim2, вызывал код, который получает _semaphoreSlim. Это может привести к тупику.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...