Потоки Windows - как сделать метод функцией потока в Windows? - PullRequest
5 голосов
/ 09 июня 2011

Конечно, я не могу передать указатель на метод в функцию CreateThread. Что мне делать?

Ответы [ 6 ]

7 голосов
/ 09 июня 2011

При использовании класса такой шаблон обычно работает хорошо:

.h

static UINT __cdecl StaticThreadFunc(LPVOID pParam);
UINT ThreadFunc();

.cpp

// Somewhere you launch the thread
AfxBeginThread(
    StaticThreadFunc,
    this);  

UINT __cdecl CYourClass::StaticThreadFunc(LPVOID pParam)
{
    CYourClass *pYourClass = reinterpret_cast<CYourClass*>(pParam);
    UINT retCode = pYourClass->ThreadFunc();

    return retCode;
}

UINT CYourClass::ThreadFunc()
{ 
    // Do your thing, this thread now has access to all the classes member variables
}
5 голосов
/ 09 июня 2011

Я часто делаю это:

class X {
private:
    static unsigned __stdcall ThreadEntry(void* pUserData) {
        return ((X*)pUserData)->ThreadMain();
    }

    unsigned ThreadMain() {
         ...
    }
};

И затем я передаю this в качестве пользовательских данных в функцию создания потоков (_beginthread [ex], CreateThread и т. Д.)

4 голосов
/ 09 июня 2011

Наиболее распространенным способом является создание класса Thread, который имеет метод run () и метод start () (эти имена заимствованы из класса Java Thread).run () - это чистый виртуальный объект, который вы перегружаете в классе, производном от Thread, для выполнения реальной работы.Метод start () внутренне вызывает CreateThread, передавая указатель this через reinterpret_cast в void *.Класс Thread также имеет статическую функцию threadEntryPoint (), которую вы передаете CreateThread.В threadEntryPoint () вы делаете reinterpret_cast обратно в Thread * и затем вызываете run () для него.

Если есть одна ситуация, в которой вы просто хотите, чтобы метод другого класса выполнялся в отдельном потоке (безнаследуя от класса Thread), вы можете создать производный от Thread класс, который получает пару указателей на объект + метод в конструкторе и вызывает их в run ().Чтобы упростить задачу, сделайте этот производный класс шаблоном.Также обратите внимание на повышение для функторных адаптеров.

1 голос
/ 13 сентября 2011

ltStartAddress CreateThread имеет тип DWORD (WINAPI * PTHREAD_START_ROUTINE) (LPVOID lpThreadParameter), и это несовместимо с функцией-членом, поскольку функция-член имеет неявный указатель this в своей подписи.Поэтому создайте статическую функцию и передайте указатель класса в качестве аргумента функции потока.

1 голос
/ 09 июня 2011

CreateThread не будет принимать указатель на функцию-член.Вы можете обернуть функцию-член в статическую функцию, которая принимает указатель на объект через lpParameter.

0 голосов
/ 09 июня 2011

Если вы говорите о родном CreateThread методе, вам, вероятно, потребуется выполнить следующие действия:

CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MyThreadProc,NULL,NULL,&threadId);

Где ваш метод обратного вызова определен как

void MyThreadProc()
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...