Лабораторная работа 3 Пантелеева БСТ1904
.docxМинистерство цифрового развития, связи и массовых коммуникаций Российской Федерации
Ордена Трудового Красного Знамени
Федеральное государственное образовательное бюджетное учреждение высшего профессионального образования
Московский технический университет связи и информатики
Кафедра Системного программирования
Лабораторная работа №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 – Синхронизация с помощью событий