Министерство науки и высшего образования РФ
Федеральное государственное бюджетное образовательное
учреждение высшего образования
«Уфимский государственный авиационный технический университет»
Факультет информатики и робототехники
Кафедра вычислительной математики и кибернетики
РАБОЧАЯ ТЕТРАДЬ
для выполнения лабораторных работ
по дисциплине «Системы реального времени»
по направлениям подготовки бакалавра
02.03.03 «Математическое обеспечение и администрирование информационных систем»
Ибрагимова К. Б., гр. МО-417 Шакиров А. Р.., гр. МО-417
Уфа 2021
Лабораторная работа № 1
«Задача ”Производитель-Потребитель” (Producer-Consumer)»
Задание:
Разработать приложение, состоящее из двух функциональных частей. Первая время от времени отправляет сообщения второй, вторая каким-то образом на них реагирует. Размер буфера передачи между этими частями – 1 сообщение, при этом первая задача (Производитель) никогда не ждет очистки буфера. Т.е. если вторая часть (Потребитель) не успевает получить помещенное в буфер сообщение, а уже возникает новое сообщение, то это новое сообщение заменяет старое, а старое - теряется. Здесь Потребитель имитирует аппаратное обеспечение СРВ. Время обработки сообщения приемником должно быть 1-2. Необходимо добиться того, чтобы при возникновении 2-3 сообщений подряд (до окончания обработки первого из них) ни одно из них не терялось, т.е. все сообщения обрабатывались Потребителем.
Описание работы приложения:
Лабораторная работа была реализована на языке программирования C#, т.к. он содержит все необходимые классы для реализации поставленной задачи. Был использован примитив синхронизации mutex.
Разработанное GUI-приложение имеет одно окно с тремя текстовыми полями, одно из которых отображает отправленные «Производителем» сообщения, а другое – получаемые «Потребителем» сообщения. По нажатию на кнопку «Создать» начинается отправка «Производителем» сообщений и отображение их в первом текстовом поле «Буфер», в третьем текстовом поле «Результат» отображаются обработанные сообщения.
Пример работы приложения:
Рисунок 1 - Пример работы mutex
Листинг программы:
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();
Thread produce;
Thread consume;
public Form1()
{
InitializeComponent();
consume = new Thread(new ThreadStart(Consume));
consume.Start();
}
private void button1_Click(object sender, EventArgs e)
{
produce = new Thread(new ThreadStart(Produce));
produce.Start();
}
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 (true)
{
var isAdd = false;
mutex.WaitOne();
if (bufer.Length > 0)
{
if (consumerBuffer.Count < 3)
{
isAdd = true;
consumerBuffer.Enqueue(bufer);
// в UI потоке печатаем
Invoke(new Action(() =>
{
listBox2.Items.Clear();
listBox2.Items.AddRange(consumerBuffer.ToArray());
textBox1.Text = "";
}));
bufer = "";
}
}
mutex.ReleaseMutex();
if (isAdd)
{
var t = new Thread(new ThreadStart(new Action(() =>
{
Thread.Sleep(1200);
Invoke(new Action(() =>
{
listBox1.Items.Add(consumerBuffer.Dequeue());
listBox2.Items.Clear();
listBox2.Items.AddRange(consumerBuffer.ToArray());
}));
})));
t.Start();
}
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
consume.Abort();
}
}
}
Вывод:
В ходе выполнения данной лабораторной работы были изучены механизмы синхронизации потоков, а именно критическая секция и мьютекс.