Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
делать №5.doc
Скачиваний:
2
Добавлен:
15.11.2019
Размер:
654.85 Кб
Скачать

Завершення потоків у Win32 арі

Функцію потоку можна завершити двома способами.

Виконати у ній звичайний оператор return (цей спосіб є найнадійнішим):

unsigned WINAPI thread_fun (void *num) {

return 0:

}

Викликати функцію _endthreadex() з параметром, що дорівнює коду повернення:

unsigned WINAPI thread_fun (void *num) {

_endthreadex(0);

}

Приєднання потоків у Win32 арі

Приєднання потоків у Win32 АРІ, подібно до очікування завершення процесів, здійснюється за допомогою функції WaitForSingleObject(). Базовий синтаксис її використання з потоками такий:

HANDLE th = (HANDLE) _beginthreadex (...);

if (WaitForSingleObject(th. INFINITE) !- WAIT_FAILED) {

//потік завершений успішно

}

CloseHandle(th);

Приклад програми для знаходження суми 8-ми чисел за допомогою процесів без розпаралелення

Листинг програми

#include <windows.h>

#include <process.h>

#include <iostream.h>

#include <conio.h>

#include <vcl.h>

int number1 = 9,number2 = 1,numb=0;

int proc1,proc2,k=0,mem[10];

unsigned tid;

HANDLE Thread[8];

DWORD res;

int i,p=2,A,B,a[8];

unsigned __stdcall Sum( void * arg) // Функція потоку

{

proc1=a[k];

proc2=a[k+1];

mem[k]=proc1+proc2;

cout<<"Комірка памяті[ "<<i<<" ]"<<mem[k]<<endl;

k+=2;

return 0;

};

unsigned __stdcall Sum2( void * arg) // Функція потоку

{

proc1=mem[k];

proc2=mem[k+p];

mem[k]=proc1+proc2;

cout<<"Комірка памяті[ "<<i<<" ]"<<mem[k]<<endl;

k+=4;

return 0;

};

int main()

{ SetConsoleOutputCP(1251);

cout<<"Введіть кількість чисел (до восьми)\n";

cin>>A;

cout<<"Введіть числа\n";

for (i=0;i<8;i++){

a[i]=0;

}

for (i=0;i<A;i++){

cin>>a[i];

}

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

Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum, 0, 0, &tid);

Sleep(10);

}

// Чекаємо, доки потоки не завершать свою работу

WaitForMultipleObjects(4, Thread, TRUE, INFINITE );

cout<<"Потоки завершили виконання"<<endl;

for (i=0;i<8;i++){

CloseHandle(Thread[i]);

}

k=0;

for (i=0;i<2;i++){

Thread[i] = (HANDLE)_beginthreadex(NULL, 0, Sum2, 0, 0, &tid);

Sleep(10);

}

// Чекаємо, доки потоки не завершать свою работу

WaitForMultipleObjects(2, Thread, TRUE, INFINITE );

cout<<"Потоки завершили виконання"<<endl;

for (i=0;i<2;i++){

CloseHandle(Thread[i]);

}

//for (i=0;i<10;i++)cout<<mem[i]<<endl;

p=4;k=0;i=0;

Thread[1] = (HANDLE)_beginthreadex(NULL, 0, Sum2, 0, 0, &tid);

Sleep(10);

cout<<"Потоки завершили виконання"<<endl;

CloseHandle(Thread[1]);

getch();

return 0;

}

Дана програма виконує знаходження суми вектору чисел, який складається не більш ніж з 8-ми елементів за допомогою потоків. Ми маємо масив а[ ] та комірки пам’яті mem. Якщо маємо масив з восьми елементів {1,2,3,4,5,6,7,8} то знайдемо суми сусідніх елементів {3,7,11,15}, і так далі до знаходження остаточного результату.

Введіть кількість чисел (до восьми)

8

Введіть числа

1

2

3

4

5

6

7

8

Комірка пам’яті [ 0 ]3

Комірка пам’яті [ 1 ]7

Комірка пам’яті [ 2 ]11

Комірка пам’яті [ 3 ]15

Потоки завершили виконання

Комірка пам’яті [ 0 ]10

Комірка пам’яті [ 1 ] 26

Потоки завершили виконання

Комірка пам’яті [ 0 ]36

Потоки завершили виконання

Рисунок 2.5 – Приклад виконання програми

Стан пам’яті під час виконання програми:

Mem1

Mem2

Mem3

Mem4

Mem5

Mem6

Mem7

Mem8

1

2

3

4

5

6

7

8

3

0

7

0

11

0

15

0

10

0

7

0

26

0

15

0

36

0

7

0

26

0

15

0

З рисунків 2.5, 2.6 видно, що програма складається з 3-х ярусів:

Алгоритм розпаралелення:

Рисунок 2.6 – Схема розпаралелення процесу

На першому ярусі за допомогою чотирьох процесорів знаходимо суму елементів а1+а2, а3+а4, а5+а6, а7+а8. Після чого результати заносимо в пам'ять.

На другому ярусі знаходимо суму даних з комірок пам’яті mem[1]+mem[3], mem[5]+mem[7], після чого результати заносимо в пам'ять.

На третьому ярусі знаходимо суму даних з комірок пам’яті mem[1]+mem[5].