Выпуск и WaitOne в семафор в C#

Я работаю над семафором, используя C#. Вот мое понимание о Release а также WaitOne методы в C#.

WaitOne Метод уменьшает количество семафоров, когда поток входит в слот, и когда он покидает слот, семафор увеличивается.

Release Метод возвращает счетчик предыдущих семафоров, верно? Мое понимание противоречит следующему коду:

  static Thread[] threads = new Thread[5];
        static Semaphore sem = new Semaphore(3,5);
        static void SemaphoreTest()
        {
            Console.WriteLine("{0} is waiting in line...", Thread.CurrentThread.Name);
            Console.WriteLine("Semaphore count : "+sem.WaitOne());
            Console.WriteLine("{0} enters the semaphore test", Thread.CurrentThread.Name);
            Thread.Sleep(300);

            Console.WriteLine("{0} is leaving the semaphore test and the semaphore count is {1}", Thread.CurrentThread.Name, sem.Release());

        }
        static void Main(string[] args)![enter image description here][2]
        {
            for (int i = 0; i < 5; i++)
            {
                threads[i] = new Thread(SemaphoreTest);
                threads[i].Name = "thread_" + i;
                threads[i].Start();

            }
            Console.Read();

Thread_2 удаляется и, следовательно, счетчик семафоров должен быть увеличен. Но этого не происходит, так как предыдущий счетчик семафоров равен 0, когда thread_0 собирается уходить. Насколько я понимаю, это должен быть один. Я прав? Кто-нибудь может объяснить это?

1 ответ

Документация описывает возвращаемое значение Release() метод как это:

Счетчик семафора до вызова метода Release

Обратите внимание, что это отличается от того, что метод возвращает значение, которое семафор имел перед выпуском.

В частности, если у вас есть два потока, участвующих в выпуске семафора, они оба могут вызвать Release() в то же время, в результате чего это значение будет одинаковым для обоих потоков. То есть вызов метода не совсем совпадает с фактическим освобождением семафора; метод должен выполнить некоторую работу до того, как семафор будет фактически выпущен, и счетчик семафора останется таким, каким он был до тех пор, пока это не произойдет.

Я также укажу: по крайней мере, когда я запускаю тест, я вижу поток № 3, получающий семафор до того, как поток № 0 сообщит о выходе. Теперь мы не знаем наверняка, в каком порядке эти операции действительно происходили (вывод консоли может фактически или не быть в точности таким же, как взаимодействия потоков с семафором), но другая возможность состоит в том, что поток № 3 получил семафор после того, как поток № 2 выпустил его, но до того, как поток № 0 выпустил его.

Существует ряд допустимых сценариев, в которых вы увидите счет 0, возвращенный последовательно.

Другие вопросы по тегам