【问题标题】:Creating a thread of a nonstatic member function? [duplicate]创建非静态成员函数的线程? [复制]
【发布时间】:2013-01-23 02:25:06
【问题描述】:

如果我有一个成员函数。 . .

MyClass::MyFunction()
{
    while(1)
    {
        //blah blah blah
    }
}

。 . .我尝试创建这个函数的线程。 . .

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)MyFunction, NULL, 0, NULL);

。 . .我总是收到一条错误消息,说 (LPTREAD_START_ROUTINE)MyFunction 是无效的类型转换,并且我无法创建非静态成员函数的线程。

我无法将我的函数设为静态,因为我多次使用 this 指针,这需要一个非静态成员函数。

有什么简单的方法可以创建非静态成员函数的线程吗?

(我正在使用 Visual Studio 2010、C++、MFC)

【问题讨论】:

标签: c++ multithreading mfc member-functions


【解决方案1】:

您应该对所有这些信息进行私有化,也许“start()”函数除外。您将拥有一个类的私有静态成员函数作为操作系统线程启动的目标,在“start()”中将对象的“this”指针传递给线程启动方法,将其转换回您的对象类型静态函数,然后在对象本身上调用您的私有主线程方法。由于静态函数是类的成员,它可以使用私有函数,而如果不是,它就不能(如果不是朋友)。我没有编译/测试这个,但想法是:

class MyObj {
private:
    void thread() {
            // this-> is valid here
    }

    static DWORD static_entry(LPVOID* param) {
        MyObj *myObj = (MyObj*)parm;
        myObj->thread();
        return 0;
    }

public:
    void start() {
        CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL);
    }
};

警告:不要在线程运行时破坏对象!您可能必须与互斥锁同步或确保线程在对象销毁时加入。如果 start() 的调用者不再管理对象,您还可以在 thread() 的末尾执行“删除此”或在 static_entry 的末尾删除 myObj。

【讨论】:

    【解决方案2】:

    创建一个静态函数

    static DWORD myFunctionCaller(LPVOID* param)  
    {
      MyClass* myClass = static_cast<MyClass*>(param);
      myClass->MyFunction();
    }
    
    CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL);
    

    缺点是你会得到一些浮动的静态函数,但你可以很容易地限制范围,这应该可以防止你创建太多线程

    【讨论】:

    • 为了避免浮动静态函数,你也可以将你的类中的静态函数定义为静态函数。
    【解决方案3】:

    没有类实例就不能调用 C++ 成员函数。 以下代码是我的建议之一;

    MyClass * instance = ...; // valid instance.
    CreateThread(NULL, 0, StartRoutine, instance, 0, NULL);
    
    DWORD WINAPI StartRoutine(LPVOID ptr) {
      static_cast<MyClass*>(ptr)->MyFunction();
    }
    

    另一个建议是用static关键字声明成员函数;

    class MyClass {
      ...
      static DWORD WINAPI MyFunction();
      ...
    }
    

    在第二个代码中,MyFunction 无法访问类(非static)成员变量。

    【讨论】:

    • 这行不通,因为在线程内部我使用了指向窗口的 this 指针。我的程序到达那条线时会崩溃。
    • 指针instance 应该指向MyClass 的正确实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 2011-05-31
    • 2012-10-20
    • 2017-05-19
    • 1970-01-01
    相关资源
    最近更新 更多