Процеси і потоки (threads) в winapi

Коли додаток починає свою роботу, для нього створюється процес (process). Зазвичай, кожній програмі відповідає один процес.

Потоки (Threads)

Кожен процес має як мінімум один потік (thread). До сих пір наші програми складалися з одного процесу і одного потоку. У цьому уроці ми навчимося створювати додаткові потоки в процесі.

Найголовніше питання про потоках: для чого потрібно кілька потоків? Різні потоки можуть одночасно виконуватися різними ядрами процесора. Наприклад, в нашій однопоточному програмі одна функція прораховує штучний інтелект, а інша - фізику взаємодії об'єктів. У цьому випадку спочатку буде виконана одна функція, а потім друга. Якщо ж ми розділимо програму на два процеси і запустимо програму на двоядерному процесорі, то штучний інтелект і фізика прораховуватимуться одночасно.

З точки зору C ++ потік - це звичайна функція має певний прототип. Для створення потоку використовується функція CreateThread.

Створення потоків - CreateThread

Функція CreateThread повертає описувач потоку:

1? HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) ;? 1!

1. lpThreadAttributes - даний аргумент визначає, чи може створюваний потік бути успадкований дочірнім процесом. Ми не будемо створювати дочірні процеси, тому ставимо NULL.

2. dwStackSize - розмір стека в байтах. Якщо передати 0, то буде використовуватися значення за замовчуванням (1 мегабайт).

4. lpParameter - покажчик на змінну, яка буде передана в потік.

5. dwCreationFlags - прапори створення. Тут можна відкласти запуск виконання потоку. Ми будемо запускати потік відразу ж, передаємо 0.

6. lpThreadId - покажчик на змінну, куди буде збережений ідентифікатор потоку. Нам ідентифікатор не потрібен, передаємо NULL.

Давайте подивимося на код виклику CreateThread:

1? HANDLE thread = CreateThread (NULL, 0, thread2, NULL, 0, NULL) ;? 1!

Функція потоку повинна відповідати наступним прототипу:

1? DWORD WINAPI ThreadProc (LPVOID lpParameter)? 1!

Аргумент, який може приймати дана функція передається четвертим параметрів функції CreateThread. Якщо відкинути всі перевизначення типів, то даний прототип виглядає так:

1? Unsigned long __stdcall ThreadProc (void * lpParameter)? 1!

Наостанок розглянемо приклад створення другого потоку:

Створення програми з двома потоками

Код програми можна завантажити на початку уроку. Це проста консольна програма. Для роботи з потоками необхідно включити файл windows.h. Розглянемо основний код:

1? DWORD WINAPI thread2 (LPVOID); int main ()