Windows 线程 - 如何使方法成为 Windows 中的线程函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6295657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:02:27  来源:igfitidea点击:

Windows threads - how to make a method a thread function in windows?

c++windowsmultithreadingwinapipointers

提问by KOLANICH

I can't pass a pointer to method to the CreateThread function, of course. What should I do?

当然,我不能将指向方法的指针传递给 CreateThread 函数。我该怎么办?

回答by DanDan

If using a class, some pattern like this usually works well:

如果使用一个类,像这样的一些模式通常很有效:

.h

。H

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

.cpp

.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
}

回答by J?rgen Sigvardsson

I often do this:

我经常这样做:

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

    unsigned ThreadMain() {
         ...
    }
};

And then I pass thisas user data to the thread creator function (_beginthread[ex], CreateThread, etc)

然后我将this用户数据作为用户数据传递给线程创建者函数(_beginthread[ex]、CreateThread 等)

回答by Fabio Ceconello

The most common way is to create a Thread class that has a run() method and a start() method (these names borrowed from the Java Thread class). run() is a pure virtual that you overload in a class derived from Thread to do the actual work. The method start() internally calls CreateThread passing the this pointer via reinterpret_cast to void*. The Thread class has also a threadEntryPoint() static function that you pass to CreateThread. In threadEntryPoint() you do a reinterpret_cast back to Thread* and then call run() on it.

最常见的方法是创建一个具有 run() 方法和 start() 方法(这些名称借自 Java Thread 类)的 Thread 类。run() 是一个纯虚拟的,您可以在从 Thread 派生的类中重载它以执行实际工作。方法 start() 在内部调用 CreateThread,通过 reinterpret_cast 将 this 指针传递给 void*。Thread 类还有一个传递给 CreateThread 的 threadEntryPoint() 静态函数。在 threadEntryPoint() 中,您对 Thread* 执行 reinterpret_cast,然后对其调用 run()。

If there's one situation in which you just want a method of another class to be executed on a separated thread (without having to inherit from the Thread class) you can create a Thread-derived class that receives a pair object+method pointers in the constructor, and calls them in run(). To ease things up, make this derived class a template. Also take a look on boost for functor adaptors.

如果有一种情况,您只想在单独的线程上执行另一个类的方法(不必从 Thread 类继承),则可以创建一个 Thread 派生类,该类在构造函数中接收一对对象 + 方法指针, 并在 run() 中调用它们。为了让事情变得简单,让这个派生类成为一个模板。还可以查看函子适配器的 boost。

回答by pepsi

CreateThread won't take a pointer to a member function. You can wrap the member function in a static function which takes the object pointer through lpParameter.

CreateThread 不会使用指向成员函数的指针。您可以将成员函数包装在一个静态函数中,该函数通过 lpParameter 获取对象指针。

回答by Vishal

CreateThread's lpStartAddress is of type DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter) and this is incompatible with the member function since the member function has an implicit thispointer in its signature. So create a static function and pass the class pointer as the argument to the thread function.

CreateThread 的 lpStartAddress 是 DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter) 类型,这与成员函数不兼容,因为成员函数在其签名中具有隐式this指针。所以创建一个静态函数并将类指针作为参数传递给线程函数。

回答by crypted

If you are talking about NativeCreateThreadMethod you would probably need to do following

如果您正在谈论本CreateThread方法,您可能需要执行以下操作

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

Where your callback method is defined as

您的回调方法定义为

void MyThreadProc()
{
}