Pull to refresh

Создание потоков средствами C++ в Win32

Сегодня я хотел бы рассказать как собственно создавать потоки функциями _beginthread и _beginthreadex. Чем же лучше использование этих функций в замен стандартных средств из winapi?

Начну с того, что они позволяют использовать внутри потока все средства CRT-библиотеки, говоря простым языком, то можно использовать функции C++ такие как cout, fprint и т.д. В случае с CreateThread, которую рассматривать я не буду, можно использовать только WinApi средства.

Для начала рассмотрим прототип первой функции:

uintptr_t _beginthread(
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);

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

void myThread(void* pParams)
{
...
}

Имя конечно же может быть любое.

Второй аргумент это начальный размер стека. Почти в любом случае его можно указать как 0. Тогда размер стека будет равен тому же, что и у главной задачи процесса.

С третьим все ещё легче, это аргументы функции потока, которые вполне могут быть как NULL. Или же выглядеть как (void*)(pParam) в случае с первой функцией.

Для полности приведу пример, который выводит 100 раз цифру 1 и 100 раз цифру 2.

#include #include <process.h>

void myThread(void* pParams)
{
for(int f=0;f<=100;f++){
std::cout << “1″;
}
_endthread();
}

int main()
{
_beginthread(myThread, 0, NULL);
for(int q=0;q<=100;q++){
std::cout << “2″;
}

system(”PAUSE”);
}

Теперь пора перейти к более функциональному собрату первой _beginthreadex. Она нужна в случае если вам понадобится в дополнение и возможности CreateThread. К примеру приостановление потока, чего нету в обычной _beginthread. Посмотрим на прототип:

unsigned long _beginthreadex(
void *Security,
unsigned StackSize,
unsigned (*StartAddress)(void*),
void *ArgList,
unsigned Initflag,
unsigned *ThrdAddr);

Теперь посмотрим на её аргументы:

Первый это указатель на дескриптор защиты. К сожалению это уже другой разговор и его я рассматривать не буду.

Второй аргумент это адрес стека. О нем речь шла ещё в первой функции.

Третий — сама функция задачи потока. О её уже было опять же рассказано в первой функции.

Четвертый — тоже уже было. см. _beginthread.

Пятый — это уже интереснее. Он используется для установки параметров задачи. Например если вы хотите создать поток в приостановленном состояние, то вам нужно установить параметр CREATE_SUSPENDED. Если не нужен можно поставить 0.

Ну и последний это адрес создания задачи.

Для выхода из потока используется _endthread(). Но в большенстве случаев его использовать не обязательно, так как после окончания потока управление само передастся главной задаче.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.