Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа 3 Пантелеева БСТ1904

.docx
Скачиваний:
35
Добавлен:
04.03.2022
Размер:
110.59 Кб
Скачать

Министерство цифрового развития, связи и массовых коммуникаций Российской Федерации

Ордена Трудового Красного Знамени

Федеральное государственное образовательное бюджетное учреждение высшего профессионального образования

Московский технический университет связи и информатики

Кафедра Системного программирования

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

по теме: «Методы синхронизации потоков»

Выполнила: Пантелеева К.А.

Группа: БСТ1904

Вариант: 13

Москва, 2021

Оглавление

Цель работы 3

Лабораторное задание 3

Код программы 3

Результаты работы 7

Цель работы

Получение практических навыков по использованию Win32 API для синхронизации потоков.

Лабораторное задание

Исследование на конкретном примере следующих методов синхронизации потоков:

1) критические секции – синхронизация для задачи вывода массивов чисел,

2) мьтексы – синхронизация для задачи 2 процессов, которые борются за один ресурс,

3) события – синхронизация для задачи вывода массивов чисел.

Задачу для синхронизации выбрать на свое усмотрение.

Код программы

os_critical.cpp

#include <iostream>

#include <Windows.h>

#include <conio.h>

using namespace std;

#define pause() cout << "Press any key to continue..." << endl; _getch()

CRITICAL_SECTION cs;

DWORD WINAPI thread(LPVOID)

{

int i, j;

for (j = 0; j < 10; j++)

{

EnterCriticalSection(&cs);

for (i = 0; i < 10; i++)

{

cout << j << ' ' << flush;

Sleep(17);

}

cout << endl;

LeaveCriticalSection(&cs);

}

return 0;

}

int main()

{

int i, j;

HANDLE hThread;

DWORD IDThread;

InitializeCriticalSection(&cs);

hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, NULL, 0, &IDThread);

if (hThread == NULL)

{

cout << "Error of creating new thread..." << endl;

pause();

return GetLastError();

}

for (j = 0; j < 20; j++)

{

EnterCriticalSection(&cs);

for (i = 0; i < 10; i++)

{

cout << j << ' ' << flush;

Sleep(17);

}

cout << endl;

LeaveCriticalSection(&cs);

}

WaitForSingleObject(hThread, 0xFFFFFFFF);

DeleteCriticalSection(&cs);

pause();

return 0;

}

os_mutex.cpp

#include <iostream>

#include <memory>

#include <string>

#include <thread>

#include <Windows.h>

#include <cstring>

struct SharedData {

int sch = 0;

char mas[8];

};

HANDLE mutex;

HANDLE mapping;

using namespace std;

int main() {

DWORD dwBytesWritten = 0;

HANDLE hFile = CreateFile(TEXT("test1.txt"), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

mapping = CreateFileMappingA(hFile, nullptr, PAGE_READWRITE, 0, sizeof(SharedData), "first1");

unique_ptr<SharedData, decltype(&UnmapViewOfFile)> data((SharedData*)MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0), UnmapViewOfFile);

mutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "first");

while (mutex == NULL) {

mutex = CreateMutexA(NULL, FALSE, "first");

}

cout << "mutex:" << mutex << endl;

DWORD dwBytesToWrite = 13;

thread user_input_thread([&] {

WaitForSingleObject(mutex, INFINITE);

for (int i = 0; i < 4; i++) {

data->mas[data->sch] = '2';

cout << "mas[" << data->sch << "]= " << data->mas[data->sch] << " ";

WriteFile(hFile, (LPCVOID)data->mas[data->sch], dwBytesToWrite, &dwBytesWritten, NULL);

Sleep(500);

data->sch++;

}

ReleaseMutex(mutex);

});

user_input_thread.join();

system("pause");

CloseHandle(hFile);

}

os_mutex2.cpp

#include <iostream>

#include <memory>

#include <string>

#include <thread>

#include <Windows.h>

#include <cstring>

struct SharedData {

int sch = 0;

char mas[8];

};

HANDLE mutex;

HANDLE mapping;

using namespace std;

int main() {

DWORD dwBytesWritten = 0;

HANDLE hFile = CreateFile(TEXT("test1.txt"), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

mapping = CreateFileMappingA(hFile, nullptr, PAGE_READWRITE, 0, sizeof(SharedData), "first1");

unique_ptr<SharedData, decltype(&UnmapViewOfFile)> data((SharedData*)MapViewOfFile(mapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0), UnmapViewOfFile);

mutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "first");

if (mutex == NULL) {

mutex = CreateMutexA(NULL, FALSE, "first");

}

cout << "mutex:" << mutex << endl;

DWORD dwBytesToWrite = 13;

thread user_input_thread([&] {

WaitForSingleObject(mutex, INFINITE);

for (int i = 0; i < 4; i++) {

data->mas[data->sch] = '3';

cout << "mas[" << data->sch << "]= " << data->mas[data->sch] << " ";

WriteFile(hFile, (LPCVOID)data->mas[data->sch], dwBytesToWrite, &dwBytesWritten, NULL);

Sleep(500);

data->sch++;

}

ReleaseMutex(mutex);

});

user_input_thread.join();

system("pause");

CloseHandle(hFile);

}

os_event.cpp

#include <stdio.h>

#include <windows.h>

HANDLE hEvent1, hEvent2;

int a[5];

HANDLE hThr;

unsigned long uThrID;

void Thread(void* pParams)

{

int i, num = 0;

while (num<20)

{

WaitForSingleObject(hEvent2, INFINITE);

for (i = 0; i < 5; i++) a[i] = num;

num++;

SetEvent(hEvent1);

}

}

int main(void)

{

hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL);

hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);

hThr = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, NULL, 0, &uThrID);

while (1)

{

WaitForSingleObject(hEvent1, INFINITE);

Sleep(1000);

printf("%d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4]);

SetEvent(hEvent2);

}

return 0;

}

Результаты работы

Вывод чисел с помощью критических секций (рисунок 1).

Рисунок 1 – Синхронизация методом критической секции

Результат синхронизации 2 потоков с помощью Mutex (рисунок 2).

Рисунок 2 – Синхронизация с использованием Mutex

Результат синхронизации с помощью событий (рисунок 3).

Рисунок 3 – Синхронизация с помощью событий