Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
РТ_Ибрагимова_Шакиров.docx
Скачиваний:
39
Добавлен:
14.09.2022
Размер:
358.26 Кб
Скачать

Список используемых источников

  1. В чем разница между мьютексом, монитором и семафором: [Электронный ресурс]. 2019. URL: https://javarush.ru/groups/posts/2174-v-chem-raznica-mezhdu-mjhjuteksom-monitorom-i-semaforom.

Лабораторная работа № 2

«Пул потоков (Thread Pool)»

Задание:

Реализовать пул потоков для усовершенствования решения лабораторной работы № 1. В случаях, когда целевая система является многопроцессорной (или даже с одним многоядерным процессором, или с технологией HyperThreading) часто есть возможность ускорить обработку поступающих событий, выполняя ее параллельно. Для обработки каждого из событий используется отдельный поток; максимальное количество потоков, разумеется, ограничивается каким-то числом, например, 2, 4 или даже 10 – зависит от мощности системы. Т. к. создание потока – дорогостоящая операция, то обычно используют так называемый пул потоков: единожды созданные N потоков в своем нормальном состоянии простаивают, ожидая запроса на выполнение задачи, для решения которой они написаны. Когда такой запрос приходит, поток переходит в активное состояние, в котором он начинает потреблять процессорное время и решает задачу. По окончании обработки поток возвращается в состояние простоя. Если в момент возникновения очередной задачи свободных потоков нет, приходится, как правило, ждать, пока один из них освободится.

Описание работы приложения:

Лабораторная работа была реализована на языке программирования C#, т. к. он содержит все необходимые классы для реализации поставленной задачи. Был создан пул потоков-потребителей, теперь обработка очереди задач производится несколькими потоками. Для синхронизации общих данных использовался Mutex.

Разработанное GUI-приложение имеет одно окно с тремя текстовыми полями, одно из которых отображает отправленные «Производителем» сообщения, а другое – получаемые «Потребителем» сообщения. По нажатию на кнопку «Создать» начинается отправка «Производителем» сообщений и отображение их в первом текстовом поле «Буфер», в третьем текстовом поле «Результат» отображаются обработанные сообщения.

Пример работы приложения:

Рисунок 2 - Пример работы программы

Листинг программы:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace RTS_Laba_1

{

public partial class Form1 : Form

{

int counter = 0;

string bufer = "";

Mutex mutex = new Mutex();

Mutex mutexConsumer = new Mutex();

Task produce;

Task consume;

Semaphore semaphore;

public Form1()

{

InitializeComponent();

ThreadPool.SetMaxThreads(10, 10);

semaphore = new Semaphore(3, 3);

//запуск Consume в потоке consume из пула

consume = Task.Run(Consume);

}

private void button1_Click(object sender, EventArgs e)

{

//запуск Produce в потоке produce из пула

produce = Task.Run(Produce);

}

void Produce()

{

mutex.WaitOne();

counter++;

bufer = $"Сообщение №{counter}";

Invoke(new Action(() =>

{

textBox1.Text = bufer;

}));

Thread.Sleep(50);

mutex.ReleaseMutex();

}

Queue<string> consumerBuffer = new Queue<string>(3);

void Consume()

{

while (!isClosed)

{

var isAdd = false;

mutex.WaitOne();

if (bufer.Length > 0)

{

if (consumerBuffer.Count < 5)

{

isAdd = true;

consumerBuffer.Enqueue(bufer);

// в UI потоке печатаем

Invoke(new Action(() =>

{

listBox2.Items.Clear();

listBox2.Items.AddRange(consumerBuffer.ToArray());

textBox1.Text = "";

}));

bufer = "";

}

}

mutex.ReleaseMutex();

if (isAdd)

{

Task.Run(() =>

{

semaphore.WaitOne();

Thread.Sleep(1200);

Invoke(new Action(() =>

{

mutexConsumer.WaitOne();

listBox1.Items.Add(consumerBuffer.Dequeue());

listBox2.Items.Clear();

listBox2.Items.AddRange(consumerBuffer.ToArray());

mutexConsumer.ReleaseMutex();

}));

semaphore.Release();

});

}

}

}

bool isClosed = false;

private void Form1_FormClosed(object sender, FormClosedEventArgs e)

{

isClosed = true;

}

}

}

Вывод:

В ходе выполнения данной лабораторной работы были получены навыки реализации пула потоков, а также усовершенствовано решение лабораторной работы № 1.