线程调用成员函数

Thread call member function

本文关键字:函数 成员 调用 线程      更新时间:2023-10-16

我需要通过线程调用类的成员函数,但我不想使用 Boost 库绑定概念,并且我必须使用的类没有任何静态函数来提供帮助。我尝试使用STL mem_fun_ref但收到编译时错误。

 base b;
 handle = CreateThread(NULL, 0,  LPTHREAD_START_ROUTINE(bind2nd(mem_fun_ref(&base::show), &b)),           
                          NULL, NULL, &dword);
class B{
public:
  void show(){
    cout << "show";
  }
};
我不知道

CreateThread()但看起来像一个用于创建线程的 C 样式接口:您可能无法传递函数对象。最有可能的是,启动函数类型在道德上等同于

extern "C" typedef void (*entry_funciont)(void*);

可能带有一些额外的参数并返回与void不同的内容。您需要一个转发函数来恢复函数对象,您需要知道作为"用户数据"传递给CreateThread()函数的函数对象的确切类型(我猜你在函数对象之后立即传递NULL。你可以使用类似这样的东西:

struct entry_base {
    virtual ~entry_base() {}
    virtual void call() = 0;
};
template <typename Fun>
struct entry
    : entry_base {
    Fun fun;
    entry(Fun fun): d_fun(fun) {}
    void call() {
        this->d_fun();
        delete this;
    }
};
template <typename Fun>
entry_base* make_entry(Fun fun) {
    return new entry<Fun>(fun);
}
extern "C" void call_entry(void* entry) {
    static_cast<entry_base*>(entry)->call();
}

。然后可以使用这样的东西:

base* b = ...; // you can't use a local object here!
handle = CreateThread(NULL, 0,
                      LPTHREAD_START_ROUTINE(&call_entry),
                      make_entry(bind2nd(mem_fun_ref(&base::show), &b)),           
                      NULL, &dword);

请注意,我正在推测CreateThread()接口,即用户数据指针很可能进入不同的位置。但是,绑定到指向本地对象的指针几乎肯定是行不通的:当线程运行时,此对象可能会超出范围,并且会删除对象运行的基础。

这是 C WinAPI 函数,下面是声明:

HANDLE WINAPI CreateThread(
  _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_       SIZE_T dwStackSize,
  _In_       LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_   LPVOID lpParameter,
  _In_       DWORD dwCreationFlags,
  _Out_opt_  LPDWORD lpThreadId
);

问题是LPTHREAD_START_ROUTINE类型定义了指向回调函数的指针,而不是C++"隐藏"此参数的方法。

以下是如何绕过它的好例子:http://blogs.msdn.com/b/oldnewthing/archive/2004/01/09/49028.aspx

class SomeClass {
 ...
 static DWORD CALLBACK s_ThreadProc(LPVOID lpParameter)
 {
  return ((SomeClass*)lpParameter)->ThreadProc();
 }
 DWORD ThreadProc()
 {
  ... fun stuff ...
 }
};