3

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

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 中工作)

4

3 回答 3

4

您应该对所有这些信息进行私有化,也许“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。

于 2013-02-07T15:57:47.150 回答
2

没有类实例就不能调用 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)成员变量。

于 2013-02-07T14:47:00.677 回答
2

创建静态函数

static DWORD myFunctionCaller(LPVOID* param)  
{
  MyClass* myClass = static_cast<MyClass*>(param);
  myClass->MyFunction();
}

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL);

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

于 2013-02-07T14:52:20.143 回答