Nano Hash - криптовалюты, майнинг, программирование

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

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

Ответы:


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()
16.01.2011
  • Ваш код будет лучше представлен в ответе, чем в комментарии. 16.01.2011
  • LOL, вероятно, это уже пятый раз, когда я получаю тот же ответ, потому что документация конструктора всегда смущает меня, какие значения устанавливать. Ваше здоровье 11.10.2016

  • 2

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

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

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

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

    20.02.2012
  • Это так полезно! Я думал о семафорах задом наперед, поскольку в initialCount указывается количество начальных ЗАБЛОКИРОВАННЫХ ресурсов, а не количество ресурсов, доступных немедленно. Спасибо. 25.03.2014
  • @PhilipTenn, согласен - документация по этому поводу не ясна 11.10.2016
  • Я согласился, они должны изменить имя переменной или обновить документы 21.02.2017
  • @Sandbox, вы должны принять этот ответ IMO, поскольку он действительно объясняет значение параметра initialCount. 22.07.2018

  • 3

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

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

    16.01.2011

    4

    Если вы хотите, чтобы ни один поток не имел доступа к вашему ресурсу в течение некоторого времени, вы передаете начальный счетчик как 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 для увеличения счетчика до максимального значения, чтобы разрешить нормальный доступ к защищенному ресурсу ».

    20.02.2012
  • Извините, я привел вам пример на C ++, хотя могу развеять сомнения. 20.02.2012
  • Цитата об инициализации очень полезна, хотя другие ответы объясняют, как работает semaphoreSlim, это единственный ответ, который имеет очень полезный пример использования этой несколько неясной функции. 12.01.2021

  • 5

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

    16.01.2011
  • Итак, вы имеете в виду, что когда я хочу, чтобы два рабочих потока получили доступ к ресурсу, я должен изменить начальное количество? 16.01.2011
  • Нет. Это текущий поток, который требует счет. Если вы не хотите, чтобы текущий поток запрашивал какой-либо проход доступа, 0 или используйте перегрузку с одним параметром. 16.01.2011

  • 6

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

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

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

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

    10.03.2017

    7

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

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

    Я действительно не понимаю значения начального подсчета?

    Initial count = Upfront cost

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

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

    22.09.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..