Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС_Лаб4.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
130.56 Кб
Скачать

Хід виконання роботи.

Приклад програми:

#include "stdafx.h"

#include <windows.h>

#include <iostream>

using namespace std;

//розмірність матриці

const int ROW = 20;

const int COL = 20;

// визначення матриці

float arr[ROW][COL];

// лічильник кількості рядків без від"ємних елементів

int k = 0;

HANDLE hChangeEvent, hCalcEvent;

DWORD WINAPI thread1 (LPVOID)

{

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

{

// чекаємо поки другий потік надасть дозвіл на зміну рядка матриці

WaitForSingleObject(hChangeEvent, INFINITE); // закоментувати

// замінюємо від"ємні елементи їх квадратами

for (int j = 0; j < COL; ++j)

{

if (arr[i][j] < 0 )

arr[i][j] = arr[i][j]*arr[i][j];

Sleep(1);

}

// встановлення події - другому потоку можна рахувати від"ємні елементи

SetEvent(hCalcEvent); // закоментувати

}

return 0;

}

DWORD WINAPI thread2 (LPVOID)

{

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

{

// чекаємо на завершення події зміни рядка матриці першим потоком

WaitForSingleObject(hCalcEvent, INFINITE); // закоментувати

// передивляємось рядок, чи є від"ємні елементи

bool IsAllPositive = true;

for (int j = 0; j < COL; ++j)

{

if (arr[i][j] < 0)

{

IsAllPositive = false;

break;

}

}

if (IsAllPositive)

++k;

// встановлення події - можна змінювати рядок матриці.

SetEvent(hChangeEvent); // закоментувати

}

return 0;

}

int main()

{

setlocale(LC_ALL, "");

HANDLE hThread1, hThread2;

DWORD IDThread;

// генерація матриці випадкових чисел

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

for (int j = 0; j < COL; ++j)

arr[i][j] = rand()%50-25;

// створення подій

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

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

// створення потоків

hThread1 = CreateThread(NULL, 0, thread1, NULL, 0, &IDThread);

if (hThread1 == NULL)

return GetLastError();

hThread2 = CreateThread(NULL, 0, thread2, NULL, 0, &IDThread);

if (hThread2 == NULL)

return GetLastError();

// Запускаємо перший потік

SetEvent(hChangeEvent);

// очікування завершення потоків

WaitForSingleObject(hThread1, INFINITE);

WaitForSingleObject(hThread2, INFINITE);

cout << "\nПотоки синхронiзовано\n";

cout << "\nКiлькiсть рядкiв без вiд\"ємних елементiв\n"

<< "(пiдрахунок у паралельному потоцi) k = " << k << endl;

// закриття дескрипторів потоків

CloseHandle(hThread1);

CloseHandle(hThread2);

CloseHandle(hChangeEvent);

CloseHandle(hCalcEvent);

return 0;

}

Щоб запустити програму без синхронізації потоків потрібно за коментувати позначені рядки.

Результат роботи програми:

До використання синхронізації:

З використанням об’єктів синхронізації:

Пояснення: Кожен потік по рядках переглядає матрицю.

В першому варіанті (без синхронізації) виконання потоку thread1 переривається потоком thread2. Тому thread1 не встигає пройти повністю рядок матриці та замінити всі від’ємні елементи квадратами. В свою чергу, потік thread2 «бачить» у рядку незмінені від’ємні елементи та не змінює лічильник k.

В другому варіанті (з синхронізацією) кожен потік чекає своєї черги на обробку рядка матриці (функція WaitForSingleObject) та передає управління іншому потоку (функція SetEvent) тільки після завершення своєї роботи.