创build线程不接受成员函数

我正在尝试创build一个networking编程的类。 这将创build一个带线程的通用套接字。

但是当我尝试使用createthread()来创build线程时。 第三个参数是产生错误。 从网上我知道,我不能使用成员函数作为createthread()的参数。

有什么我能做到的吗?

Solutions Collecting From Web of "创build线程不接受成员函数"

处理这个问题的最简单的方法是创建一个“存根”(stub)函数。

UINT tid HANDLE hThread = CreateThread(NULL, 0, myThreadStub, this, 0, &tid); .... unsigned long WINAPI myThreadStub(void *ptr) { if (!ptr) return -1; return ((MyClass*)ptr)->ThreadMain(); } 

CreateThread()允许您将参数传递给线程函数(CreateThread()调用的参数4)。 你可以使用它来传递一个指向你的类的指针。 然后可以让线程桩将该指针转换回适当的类型,然后调用成员函数。 你甚至可以让“myThreadStub”成为“MyClass”的静态成员,允许它访问私有成员和数据。

如果你已经安装了boost,你可以使用boost :: bind来创建一个存根函数。 我从来没有尝试过在Windows上,所以我不能肯定它会工作(因为回调函数必须是一个WINAPI调用),但如果它的工作,它会看起来像这样:

 HANDLE hThread = CreateThread(NULL, 0, boost::bind(&MyClass::ThreadFunction, this), NULL, 0, &tid); 

线程函数是一个非静态成员函数,它接受一个void *参数。

有一个简单的方法来解决这个问题。

看看ThreadProc回调函数 :


     DWORD WINAPI ThreadProc(
       __in LPVOID lpParameter
     );

现在在CreateThread函数中 :


     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
     );

使用静态方法作为线程过程,但是使用成员方法调用它,并将对象指针传递给它:


     #include <windows.h>

     class MyClass {
     上市:
       void CreateThreadForObject(){
         LPSECURITY_ATTRIBUTES security_attributes = 0;
         SIZE_T stack_size = 0;
         LPTHREAD_START_ROUTINE start_routine =&MyClass :: ThreadProcForObject;
         LPVOID param = this;
         DWORD creation_flags = 0;
         LPDWORD thread_id = 0;
         CreateThread(security_attributes,stack_size,start_routine,param,
                      creation_flags,thread_id);
       }

     私人的:
      静态DWORD WINAPI ThreadProcForObject( LPVOID参数 ){
         MyClass * instance = reinterpret_cast <MyClass *>(param);
        如果(!instance)返回1;
         // ...
        返回0;
       }
     };

对不起,我只是没有足够的时间写一个好例子。 但是我认为你明白了道路。

在失去了我得到它,事实是,在CreateThread,如果你通过套接字,那么没有任何问题。 因为CreateThread 正在照顾那个套接字 。 但是,如果作为拥有该套接字的对象传递,则CreateThread 不处理 套接字 ,并且在新线程中无效套接字结束。

下面的成功代码

 SOCKET s=socket(....); bind(s,...); listen(s,...); SOCKET temp=accept(s,(sockaddr *)&addrNew,&size); DWORD threadId; HANDLE thread=CreateThread(NULL,0,&MyThreadFunction,(LPVOID)(temp),0,&threadId);