служит для передачи данных. Поэтому потоку, которому требуется сетевое соединение, все равно, какое именно соединение он получит. В данном случае семафор обеспечивает удобный механизм управления доступом к сетевым соединениям.
Семафор реализуется в классе 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;
// Этот поток разрешает одновременное выполнение // только двух своих экземпляров, class MyThread {
public Thread Thrd;
// Здесь создается семафор, дающий только два // разрешения из двух первоначально имеющихся, static Semaphore sem = new Semaphore(2, 2);
public MyThread(string name) {
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd. Start () ;
}
// Точка входа в поток, void Run() {
Console.WriteLine(Thrd.Name + ' ожидает разрешения.');
sem.WaitOne();
Console.WriteLine(Thrd.Name + ' получает разрешение.');
for(char ch='A'; ch < 'D'; ch++) {
Console.,WriteLine (Thrd.Name + ' : ' + ch + ' ');
Thread.Sleep(500);
}
Console.WriteLine(Thrd.Name + ' высвобождает разрешение.');
// Освободить семафор, sem.Release();
}
}
