Выпуск и 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, возвращенный последовательно.