Подтвердить что ты не робот

Семафор - Каково использование начального счета?

http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim.aspx

Чтобы создать семафор, мне нужно указать начальный счетчик и максимальное количество. MSDN утверждает, что начальный счетчик -

Исходное количество запросов для семафор, который может быть предоставлен одновременно.

Пока указывается, что максимальное количество

Максимальное количество запросов для семафор, который может быть предоставлен одновременно.

Я могу понять, что максимальное количество - это максимальное количество потоков, которые могут одновременно обращаться к ресурсу. Но каково использование начального счета?

Если я создаю семафор с начальным числом 0 и максимальным числом 2, ни один из моих потоков потока не сможет получить доступ к ресурсу. Если я установил начальный счет как 1, а максимальное число равно 2, то поток ресурсов потока может получить доступ к ресурсу. Только когда я устанавливаю как начальный счет, так и максимальный счет как 2, 2 потока могут одновременно обращаться к ресурсу. Итак, я действительно запутался в значении исходного счета?

SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 2); //all threadpool threads wait
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 2);//only one thread has access to the resource at a time
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2, 2);//two threadpool threads can access the resource concurrently
4b9b3361

Ответ 1

Да, когда начальное число устанавливает значение 0 - все потоки будут ждать, пока вы увеличите свойство CurrentCount. Вы можете сделать это с помощью Release() или Release (Int32).

Release (...) - увеличит счетчик семафора

Подождите (...) - уменьшит его

Вы не можете увеличивать счетчик (свойство "CurrentCount" ) больше максимального количества, которое вы установили при инициализации.

Например:

SemaphoreSlim^ s = gcnew SemaphoreSlim(0,2); //s->CurrentCount = 0
s->Release(2); //s->CurrentCount = 2
...

s->Wait(); //Ok. s->CurrentCount = 1
...

s->Wait(); //Ok. s->CurrentCount = 0
...

s->Wait(); //Will be blocked until any of the threads calls Release()

Ответ 2

Итак, я действительно запутался в значении начального счета?

Важным моментом, который может помочь здесь, является то, что Wait уменьшает количество семафоров и Release увеличивает его.

initialCount - это количество доступа к ресурсам, которое будет разрешено немедленно. Или, другими словами, это количество раз Wait можно вызвать без блокировки сразу после создания семафора.

maximumCount - это наивысший счет, который может получить семафор. Это число раз Release может быть вызвано без выброса исключения, если initialCount count равен нулю. Если для параметра initialCount установлено то же значение, что и maximumCount, то вызов Release сразу после создания семафора вызовет исключение.

Ответ 3

Сколько потоков вы хотите получить доступ к ресурсу сразу? Установите начальный счет на этот номер. Если это число никогда не будет увеличиваться на протяжении всей жизни программы, установите максимальное количество масок и на этот номер. Таким образом, если у вас есть ошибка программирования в том, как вы освобождаете ресурс, ваша программа выйдет из строя и сообщит вам.

(Существует два конструктора: один, который принимает только начальное значение, и тот, который дополнительно принимает максимальное значение. Используйте то, что подходит).

Ответ 4

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

Ответ 5

Если вы хотите, чтобы ни один поток не обращался к вашему ресурсу в течение некоторого времени, вы передаете начальный счет как 0 и когда вы хотите предоставить доступ ко всем из них сразу после создания семафора, вы передаете значение начального счета равным до максимального количества. Например:

hSemaphore = CreateSemaphoreA(NULL, 0, MAX_COUNT, NULL) ;

//Do something here
//No threads can access your resource

ReleaseSemaphore(hSemaphore, MAX_COUNT, 0) ;

//All threads can access the resource now

Как указано в документации MSDN: "Другое использование ReleaseSemaphore во время инициализации приложения. Приложение может создавать семафор с начальным количеством ноль. Это устанавливает состояние семафора несигнализованным и блокирует доступ всех потоков к защищенному ресурсу. Когда приложение завершит свою инициализацию, оно использует ReleaseSemaphore, чтобы увеличить счетчик до его максимального значения, чтобы обеспечить нормальный доступ к защищенному ресурсу."

Ответ 6

Как MSDN объясняет это в разделе "Примечания":

Если значение initialCount меньше максимума, то эффект будет таким же, как если бы текущий поток вызывал WaitOne (максимумCount минус initialCount) раз. Если вы не хотите резервировать записи для потока, который создает семафор, используйте тот же номер для maximumCount и initialCount.

Итак, если начальный счет равен 0, а max равен 2, то, как если бы WaitOne вызывался дважды по основному потоку, мы достигли емкости (количество семафоров теперь равно 0), и ни один поток не может войти в Семафор. Аналогично, если начальный счет равен 1, а max - 2, WaitOnce был вызван один раз, и только один поток может войти, прежде чем мы снова достигнем емкости и так далее.

Если для начального счета используется 0, мы всегда можем вызвать Release (2), чтобы увеличить счет семафора до max, чтобы максимальное количество потоков могло получить ресурс.