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

Lab5

.docx
Скачиваний:
7
Добавлен:
28.06.2021
Размер:
86.25 Кб
Скачать

ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ

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

высшего профессионального образования

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

----------------------------------------------------------------------------------------------------

Кафедра Математической кибернетики и информационных технологий

ЛАБОРАТОРНАЯ РАБОТА № 5

по дисциплине

ОПЕРАЦИОННЫЕ СИСТЕМЫ

на тему:

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

Выполнил:

Проверил:

Королькова Т.В.

ст.пр. кафедры МКиИТ

Москва 2017

Цель работы

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

Задание

  1. Наименование лабораторной работы, ее цель.

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

    • критические секции

    • мьютексы

    • события

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

  1. Примеры разработанных приложений (описание программ, результаты и тексты программ).

Разработанное программное обеспечение

1)В качестве задачи, предназначенной для синхронизации потоков методом критических секций, была выбрана задача синхронизации двух потоков одного процесса:

  • Поток, заполняющий массив, состоящий из 100 элементов, квадратами индексов каждого из элементов.

  • Поток, обнуляющий все элементы массива.

Исходный код проекта:

#include <windows.h>

#include <tchar.h>

#include <strsafe.h>

#include <iostream>

using namespace std;

CRITICAL_SECTION CriticalSection;

void FillArray(int*);

void NullArray(int*);

void main()

{

HANDLE ThreadsArray[2];

DWORD ThreadsArrayID[2];

int* array[100];

for (int i = 0;i < 100;i++)

array[i] = 0;

if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x00000400))

return;

ThreadsArray[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FillArray, array, CREATE_SUSPENDED, &ThreadsArrayID[0]);

ThreadsArray[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NullArray, array, CREATE_SUSPENDED, &ThreadsArrayID[1]);

if (ThreadsArray[0] == NULL || ThreadsArray[1] == NULL)

{

cout << "Something went wrong!";

Sleep(10000);

ExitProcess(3);

}

ResumeThread(ThreadsArray[0]);

ResumeThread(ThreadsArray[1]);

Sleep(10000);

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

{

printf("Array: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d \n", array[i * 10 + 0], array[i * 10 + 1], array[i * 10 + 2], array[i * 10 + 3], array[i * 10 + 4], array[i * 10 + 5], array[i * 10 + 6], array[i * 10 + 7], array[i * 10 + 8], array[i * 10 + 9]);

}

Sleep(30000);

}

void FillArray(int* array)

{

::EnterCriticalSection(&CriticalSection);

for (int i = 0; i < 100;i++)

{

array[i] = i*i;

cout << "First stream is working\n";

}

/:LeaveCriticalSection(&CriticalSection);

return;

}

void NullArray(int* array)

{

::EnterCriticalSection(&CriticalSection);

for (int i = 99;i >= 0;i--)

{

array[i] = 0;

cout << "Second stream is working\n";

}

::LeaveCriticalSection(&CriticalSection);

return;

}

2)В качестве задачи, предназначенной для синхронизации потоков методом мьютекса, была выбрана задача синхронизации потоков двух разных приложений. В случае, если время ожидания одного из потоков заканчивается, приложения прекращает свою работы и закрывается. Потоки не выполняют свою работу. Поток первого приложения выполняет:

  • Изменение регистра текста в отображенной на память файле.

Поток второго приложения выполняет:

  • Заменяет все буквы “A” на “n” и “N” на “a”.

Исходный код первого проекта:

#include <Windows.h>

#include <stdio.h>

#include <conio.h>

#include <cstring>

#include <tchar.h>

using namespace std;

void reverse(const char*, char*);

DWORD WINAPI reverseTextFull();

HANDLE hMutex;

void main()

{

HANDLE Thread;

DWORD ThreadID;

hMutex = CreateMutex(NULL, FALSE, _T("MyMutex"));

reverseTextFull();

}

DWORD WINAPI reverseTextFull()

{

HANDLE hFile;

char* pBuf;

HANDLE hMap;

hFile = CreateFile(TEXT("C:\\Users\\User\\Documents\\C++\\lab5_os.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)

{

printf("Couldn't open file");

Sleep(10000);

return 0;

}

hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, L"lab5Map.txt");

if (hMap == NULL)

{

_tprintf(TEXT("Couldn't map the file. (%d). \n"), GetLastError());

CloseHandle(hMap);

return 0;

}

pBuf = (char*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

char* pBufOut = new char[strlen(pBuf) + 1];

reverse(pBuf, pBufOut);

CopyMemory((PVOID)pBuf, pBufOut, strlen(pBufOut));

delete[] pBufOut;

UnmapViewOfFile(pBuf);

CloseHandle(hMap);

CloseHandle(hFile);

return 0;

}

void reverse(const char* pBuf, char* pBufOut)

{

DWORD dwWaitResult;

dwWaitResult = WaitForSingleObject(hMutex, 5000L);

if (dwWaitResult == WAIT_TIMEOUT)

{

printf("Tired of waiting...");

Sleep(5000);

return;

}

Sleep(15000);

for (pBuf;*pBuf != '\0';pBuf++, pBufOut++)

{

if (islower(*pBuf))

*pBufOut = toupper(*pBuf);

else

*pBufOut = tolower(*pBuf);

}

*pBufOut = '\0';

ReleaseMutex(hMutex);

}

Исходный код второго проекта:

#include <Windows.h>

#include <stdio.h>

#include <conio.h>

#include <cstring>

#include <tchar.h>

using namespace std;

int changeAllA(const char*, char*);

void changeAllAFull();

HANDLE hMutex;

void main()

{

HANDLE Thread;

DWORD ThreadID;

hMutex = CreateMutex(NULL, FALSE, _T("MyMutex"));

changeAllAFull();

}

void changeAllAFull()

{

HANDLE hFile;

char* pBuf;

HANDLE hMap;

hFile = CreateFile(TEXT("C:\\Users\\User\\Documents\\C++\\lab5_os.txt"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)

{

printf("Couldn't open file");

return;

}

hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, L"lab5Map1.txt");

if (hMap == NULL)

{

_tprintf(TEXT("Couldn't map the file. (%d). \n"), GetLastError());

CloseHandle(hMap);

return;

}

pBuf = (char*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

char* pBufOut = new char[strlen(pBuf) + 1];

if (changeAllA(pBuf, pBufOut) == 1)

CopyMemory((PVOID)pBuf, pBufOut, strlen(pBufOut));

delete[] pBufOut;

UnmapViewOfFile(pBuf);

CloseHandle(hMap);

CloseHandle(hFile);

}

int changeAllA(const char* pBuf, char* pBufOut)

{

DWORD dwWaitResult;

dwWaitResult = WaitForSingleObject(hMutex, 5000L);

if (dwWaitResult == WAIT_TIMEOUT)

{

printf("Tired of waiting...");

Sleep(5000);

return 0;

}

for (pBuf;*pBuf != '\0';pBuf++, pBufOut++)

{

if (*pBuf == 'A')

*pBufOut = 'n';

else if (*pBuf == 'N')

*pBufOut = 'a';

else

*pBufOut = *pBuf;

}

*pBufOut = '\0';

ReleaseMutex(hMutex);

return 1;

//

}

3)В качестве задачи, предназначенной для синхронизации потоков методом события, была выбрана задача синхронизации потоков одного приложения. Первый поток создает событие и устанавливает его в состояние занято. Два других потока находятся в состоянии ожидания до тех пор, пока первый не выполнит свою работу.

Исходный код проекта:

#include <string.h>

#include "windows.h"

#include <iostream>

#include "process.h"

#include <cstring>

#include <tchar.h>

using namespace std;

HANDLE event;

void Test2(void *);

void Test3(void *);

void main()

{

int i = 0;

event = CreateEvent(NULL, TRUE, FALSE, _T("FirstStep"));

DWORD ThreadsID[2];

HANDLE Threads[2];

Threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Test2, 0, 0, &ThreadsID[0]);

Threads[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Test3, 0, 0, &ThreadsID[1]);

if (event != NULL) {

while (true)

{

Sleep(500);

i++;

cout << i <<endl;

if (i % 10 == 0)

{

SetEvent(event);

Sleep(1000);

ResetEvent;

}

if (i == 100)

{

CloseHandle(event);

return;

}

}

}

else {

cout << "error create event" << endl;

}

system("pause");

}

void Test2(void *)

{

if (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)

cout << "Its a ten \n" << endl;

}

void Test3(void *)

{

if (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0)

cout << "How nice!\n" << endl;

}

Результаты выполнения проектов: