Семафоры особенно полезны в тех случаях, когда общий ресурс состоит из группы или пула ресурсов. Например, пул ресурсов может состоять из целого ряда сетевых соединений, каждое из которых служит для передачи данных. Поэтому потоку, которому требуется сетевое соединение, все равно, какое именно соединение он получит. В данном случае семафор обеспечивает удобный механизм управления доступом к сетевым соединениям.
Семафор реализуется в классеSystem. Threading. Semaphore,у которого имеется несколько конструкторов. Ниже приведена простейшая форма конструктора данного класса:
public Semaphore(int
где
Семафор применяется таким же образом, как и описанный ранее мьютекс. В целях получения доступа к ресурсу в коде программы вызывается методWaitOne() для семафора. Этот метод наследуется классомSemaphoreот классаWaitHandle.МетодWaitOne() ожидает до тех пор, пока не будет получен семафор, для которого он вызывается. Таким образом, он блокирует выполнение вызывающего потока до тех пор, пока указанный семафор не предоставит разрешение на доступ к ресурсу.
Если коду больше не требуется владеть семафором, он освобождает его, вызывая методRelease (). Ниже приведены две формы этого метода.
public int Release()
public int Release(int
В первой форме методRelease() высвобождает только одно разрешение, а во второй форме — количество разрешений, определяемых параметром
МетодWaitOne() допускается вызывать в потоке несколько раз перед вызовом методаRelease(). Но количество вызовов методаWaitOne() должно быть равно количеству вызовов методаRelease() перед высвобождением разрешения. С другой стороны, можно воспользоваться формой вызова методаRelease(int
Ниже приведен пример программы, в которой демонстрируется применение семафора. В этой программе семафор используется в классеMyThreadдля одновременного выполнения только двух потоков типаMyThread.Следовательно, разделяемым ресурсом в данном случае является ЦП.
// Использовать семафор.
using System;
using System.Threading;