Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Старое / АОПИ. Глава 2. Конспекты (02_04_19).rtf
Скачиваний:
65
Добавлен:
10.09.2019
Размер:
363.46 Кб
Скачать

Функция создания вторичного потока

HANDLE CreateThread(

IN PSECURITY_ATTRIBUTES psAttr,

IN DWORD cbStack,

IN PTHREAD_START_ROUTINE pfnStartAddr,

IN PVOID pvParam,

IN DWORD fdwCreate,

IN PDWORD pdwThreadID

);

Функция завершения дочернего потока из самого дочернего потока (only c)

В C++ не требуется вызов данной функции. В C вызов этой функции осуществляется в конце функции потока, перед возвратом (перед return 0;).

void ExitThread(

IN DWORD dwExitCode /// Код возврата

);

Функция завершения дочернего потока из потока родителя

Функция обычно вызывается в потоке-родителе, который создал дочерний поток.

BOOL TerminateThread(

IN HANDLE hThread, /// Handle

IN DWORD dwExitCode /// Код возврата

); /// TRUE, если успешно, иначе FALSE

Краткое описание.

Система выделяет память под стек потока из адресного пространства процесса. Новый поток выполняется в контексте того же процесса, что и родительский поток. Поэтому он получает доступ ко всем описателям объектов ядра, всей памяти и стекам всех потоков в процессе. За счет этого потоки в рамках одного процесса могут легко взаимодействовать друг с другом.

Параметры и описание:

(1) psAttr является указателем на структуру SECURITY_ATTRIBUTES. Если Вы хотите, чтобы объекту ядра «поток» были присвоены атрибуты защиты по умолчанию, передайте NULL.

(2) cbStack определяет размер адресного пространства потока. Каждому потоку выделяется отдельный стек. Если указано нулевое значение, CreateThread создает стек для нового потока, используя информацию, встроенную компоновщиком в EXE-файл.

(3) pfnStartAddr определяет указатель на определяемую приложением функцию, которая будет выполняться потоком.

(4) pvParam определяет указатель на переменную для передачи в поток (переменная может принимать числовое значение).

(5) fdwCreate определяет дополнительные флаги, управляющие созданием потока. Может принимать 0 (поток запускается сразу после создания) или CREATE_SUSPENDED (0x00000004; поток создается в приостановленном состоянии и не запускается до тех пор, пока не будет вызвана функция ResumeThread).

(6) pdwThreadID определяет указатель на переменную, которая получает идентификатор потока. Если этот параметр равен NULL, идентификатор потока не возвращается (в Windows 95/98 это приведет к ошибке).

Возвращаемое значение.

Если функция завершается успешно, возвращаемое значение является дескриптором нового потока.

Если функция завершается с ошибкой, возвращаемое значение равно NULL.

Пример (C++).

Программа создает поток, который открывает файл и записывает в него строку «Hello, world! Param: » и значение измененной в этом потоке глобальной переменной.

#include <iostream>

#include <fstream>

#include <windows.h>

using namespace std;

int MY_PARAM = 1; /// Глобальная переменная

DWORD WINAPI SecondThread(PVOID pvParam) {

/// Выполняется обработка

MY_PARAM = MY_PARAM + 4;

ofstream my_file;

my_file.open("spec_file.txt"); /// Открываем файл

If (my_file.Is_open()) { /// Если удалось открыть

my_file << "Hello, world! Param: " << MY_PARAM;

my_file.close(); /// Закрываем файл

}

return 0;

}

int main() {

/// Подготовка

int x = 0;

DWORD dwThreadId;

/// Создаем новый поток

HANDLE hThread = CreateThread(NULL, 0, SecondThread, (PVOID) &x, 0, &dwThreadId);

/// Даем 5 с на выполнение

WaitForSingleObject(hThread, 5000);

/// Закрываем описатель этого потока

CloseHandle(hThread);

/// В итоге наш поток закончил работу

return 0;

}

Дополнительная информация.

Если вы пользуетесь небезопасными в многопоточной среде функциями, то должны создавать потоки библиотечной функцией _beginthreadex.

Функция _beginthreadex существует только в многопоточных версиях библиотеки C/C++. Связав проект с однопоточной библиотекой, Вы получите от компоновщика сообщение об ошибке «unresolved external symbol».

_beginthreadex функция позволяет лучше контролировать способ создания потока, чем _beginthread. Есть и другие различия, но лучше всего использовать функцию _beginthreadex.