Главная страница

лабараторная работа. Теория_к_лабораторным. 1. Применение параллельных вычислений


Скачать 0.7 Mb.
Название1. Применение параллельных вычислений
Анкорлабараторная работа
Дата24.10.2021
Размер0.7 Mb.
Формат файлаdoc
Имя файлаТеория_к_лабораторным.doc
ТипДокументы
#254886
страница7 из 9
1   2   3   4   5   6   7   8   9

Семафоры


Семафоры – это еще один инструмент управления потоками. Семафоры используют в тех случаях, когда необходимо ограничить число потоков, одновременно выполняющих определенный участок кода. Бывает, что вводят подобные ограничения на доступ к разделяемому ресурсу, который теоретически может обслуживать несколько потоков одновременно, но желательно число таких “клиентов” ограничить. Если вернуться к демонстрационной программе, то там семафоры, установленные на “пути следования” потоков в количестве 2 штуки, призваны “останавливать толпу” и пропускать на определенных отметках лишь ограниченное число потоков за условную единицу времени: по 4 потока на первой отметке и по 2 потока на второй. На картинке выше видно, что первые 4 потока уже пропущены первым семафором, а остальные либо “оформляются на таможне”, либо "ждут своей очереди". Семафор в случае .Net Framework – это экземпляр классаSemaphore, который ограничивает число потоков на участке кода от места вызова метода WaitOne(), до места вызова метода Release(). Максимальное число потоков определяется конструктором класса. Все детали можно изучить, посмотрев на фрагменты исходного кода ниже, но сразу хочу обратить внимание на работу с семафором с использованием оператора try-finally, поскольку необходимо гарантировать освобождение семафора независимо от того, возникнут ли исключительные ситуации в границах его критической секции или нет.

//Пример 5. Диспетчеризация потоков

//Список потоков

private List<Thread> m_Threads;

//Список элементов управления 'ProgressBar'

private List<ProgressBar> m_ThreadDispatchingBars;

//События, управляющие потоками

//Событие с автоматическим 'повторным' включением

private AutoResetEvent m_AutoEvent;

//Событие с ручным 'повторным' включением

private ManualResetEvent m_ManualEvent;

//Текущий режим управления потоками с использованием событий

private bool m_IsAutoEvent = false;

//Семафоры, управляющие потоками

//Семафор с пропускной способностью 4, установленный на отметке 2000

private Semaphore m_Semaphore2000;

//Семафор с пропускной способностью 2, установленный на отметке 7000

private Semaphore m_Semaphore7000;

private void btnStartThreadDispatching_Click(object sender, EventArgs e)

{

//Инициализация/завершение работы коллекции потоков

if (m_Threads != null)

{

foreach (Thread _Thread in m_Threads)

try

{

//Если текущий поток активен, то прерываем его и дожидаемся

//окончания его работы

if (_Thread.IsAlive)

{

_Thread.Abort();

_Thread.Join();

}

}

catch {}

m_Threads.Clear();

}

else

{

m_Threads = new List<Thread>();

}

//...

//<исходный код частично отсутствует>

//...

//Инициалиазция событий

m_AutoEvent = new AutoResetEvent(false);

m_AutoEvent.Reset();

m_ManualEvent = new ManualResetEvent(false);

m_ManualEvent.Reset();

//Инициализация семафоров величиной пропускной способности и

//количеством заранее зарезервированных 'входов'

m_Semaphore2000 = new Semaphore(4, 4);

m_Semaphore7000 = new Semaphore(2, 2);

//Инициализация с использованием псевдо-случайных чисел и старт

System.Random _rnd;

_rnd = new System.Random();

for (int
1   2   3   4   5   6   7   8   9


написать администратору сайта