Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 3. Синхронизация потоков.docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
203 Кб
Скачать
☆

Класс Semaphore

Класс Semaphore предназначен для управления доступом к пулу ресурсов. Потоки производят вход в семафор, вызывая метод WaitOne(), и освобождают семафор при вызове метода Release(). Semaphore похож на Mutex, за исключением того, что он предоставляет одновременный доступ к общему ресурсу не одному, а нескольким потокам. Счетчик на семафоре уменьшается на единицу каждый раз, когда в семафор входит поток, и увеличивается на единицу, когда поток освобождает семафор. Когда счетчик равен нулю, последующие запросы блокируются, пока другие потоки не освободят семафор. Когда семафор освобожден всеми потоками, счетчик имеет максимальное значение, заданное при создании семафора.

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

Ниже приведена форма конструктора данного класса:

public Semaphore(int initialCount, int maximumCount)

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

maximumCount - максимальное значение данного счетчика, т.е. максимальное количество разрешений, которые может дать семафор.

Семафор применяется таким же образом, как и Mutex. В целях получения доступа к ресурсу в коде программы используется метод WaitOne() для семафора. Этот метод ожидает до тех пор, пока не будет получен семафор, для которого он вызывается. Таким образом, он блокирует выполнение вызывающего потока до тех пор, пока указанный семафор не предоставит разрешение на доступ к ресурсу.

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

public int Release()

public int Release(int releaseCount)

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

Класс Barrier

Класс Barrier - это сигнальная конструкция, которая появилась в .Net Framework 4.0. Он реализует барьер потока исполнения, который позволяет множеству потоков встречаться в определенном месте во времени. Данный метод применяется для участников, нуждающихся в синхронизации, до тех пор, пока задание остается активным, динамически могут добавляться дополнительные участники, например, дочерние задачи, создаваемые из родительской задачи. Эти участники могут ожидать, пока все остальные участники не выполнят свою работу. Этот класс эффективный, поскольку построен на основе Wait(), Pulse() и спин-блокировок.

Для использования этого класса необходимо:

  1. Создать экземпляр, указав количество потоков, которые будут встречаться одновременно;

  2. Каждый поток, должен вызывать метод SignalAndWait().

Метод SignalAndWait() cсообщает, что участник достиг барьера (Barrier) и ожидает достижения барьера другими участниками. Ниже приведена форма этого метода:

public void SignalAndWait()

Пример использования класса Barrier приведен ниже:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace BarrierProgram

{

class Program

{

static Barrier barrier = new Barrier(3);

static void Main(string[] args)

{

new Thread(Speak).Start();

new Thread(Speak).Start();

new Thread(Speak).Start();

}

static void Speak()

{

for (int i = 0; i < 5; i++)

{

Console.Write(i + " ");

barrier.SignalAndWait();

}

Console.ReadLine();

}

}

}

Как видно из результата выполнения программы (Рис. 5.7), каждый из трех потоков выводит числа от 0 до 4, одновременно с другими потоками.

увеличить изображение Рис. 5.7. Результат выполнения программы с использованием класса Barrier

Если же не использовать класс Barrier ,а именно убрать из кода данную строчку: barrier.SignalAndWait() - программа выведет числа в случайном порядке (Рис. 5.8).

увеличить изображение Рис. 5.8. Результат выполнения программы без использования класса Barrier

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]