2012-04-16 115 views
1

我有一个关于一行为我不太明白问题:C++传递对象给一个线程

我有C++代码两个变化:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) connectionSocket, 0, NULL); 

螺纹:

Client a; 
a.clientsocket = connectionSocket; 
a.testText() 
a.sendSocket(); 

工作得很好(sendSocket发送一些测试数据到套接字)。

但是,如果我这样做

Client a; 
a.clientsocket = connectionSocket; 
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) &a, 0, NULL); 

,并使用 螺纹:

a.testText(); 
a.sendSocket(); 

仅testText()的作品。

我有点困惑,这是为什么。我对C++的一个业余爱好者,虽然:-)

编辑:

添加客户端类:

class Client 
{ 
public: 
    SOCKET clientsocket; 

    Client() 
{ 
} 
~Client(){} 
void displayMessage() 
{ 
     std::cout << "test message client class" << std::endl; 
} 
int sendSocket() 
{ 
    char *sendbuf = "CLIENT TEST"; 
    send(clientsocket, sendbuf, (int)strlen(sendbuf),0); 
    closesocket(clientsocket); 
    return 0; 

} 
}; 
+0

当你第二次调用'a.sendSocket()'时会发生什么?有某种例外或某种东西?应用程序崩溃了吗? – Kiril 2012-04-16 18:24:24

+0

no不会崩溃,它只是不会向connectionSocket发送数据。 a.clientsSocket – user912877 2012-04-16 18:44:28

+0

调试器中的'a.clientSocket'看起来如何?它仍然有效吗? – Kiril 2012-04-16 18:46:51

回答

0

匿名 可能是在正确的轨道上的东西超出范围,但我认为这是connectionSocket。然而,当你说a.sendSocket()不起作用时,你将不得不提供更多的细节。应用程序崩溃了吗?你有没有发现异常?应用程序是否继续工作,但sendSocket()调用并未导致实际发送内容? 实际问题是什么?

+0

应用程序不会崩溃,sendSocket()会在connectionSocket上发送文本消息。在第一个版本中,它确实发送了它,而在第二个版本中则没有。我想要做的是将一个对象传递给一个线程,包括套接字作为对象的公共变量。这样做的原因是我可以实例化并访问线程外部的对象。 – user912877 2012-04-16 18:37:46

+0

它看起来像'connectionSocket'是一个指向实际套接字的指针,所以我建议您在将它传递给线程后验证它没有被销毁。你必须确保套接字的生命期足够长,以便线程可以使用它。 – Kiril 2012-04-16 18:40:56

+0

“实际问题”是,除非我在线程中实例化对象,我显然不能写入a.clientsocket。我想实例化线程外的对象。它不会发送任何东西(我可以在客户端看到) – user912877 2012-04-16 18:50:22

2

我猜,在你的主线程中的CreateThread成功,然后再你的客户端变量,一个,超出了范围,因此被破坏。

+0

我认为他的'connectionSocket'超出了范围。如果它是客户端,那么'a.testText()'不起作用。 – Kiril 2012-04-16 18:23:33

+0

我正在传递&a通过CreateThread()和a.testText()在线程中工作。那么它是如何超出范围的? – user912877 2012-04-16 18:24:57

+0

a.sendSocket()使用a.clientsocket ...不应该被保存在对象中? – user912877 2012-04-16 18:26:12

0

在第一种情况下,您传递一个connectionSocket,在第二种情况下,指向一个是Client类型的指针。也许你的意思是:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) a.clientsocket, 0, NULL); 
0

在我看来,它是一个超出范围的对象。 SOCKET只是一个int HANDLE值并存储在一个成员中。当创建线程运行时,'a'在线程创建函数中超出范围,(或者在下一个accept()返回时损坏)。

Try:

Client a = new Client();

在分配多线程代码中的堆栈中的对象之前,请考虑15次,然后决定动态分配。

PS - @Anon先到那里 - 我没有注意到。

0

从客户端类

SOCKET clientsocket; 

只要你传递上到一个线程,则SOCKET将不得不调用它的拷贝构造函数。这个拷贝构造函数可能是未定义的,或者它可能试图在同一个端口上打开一个新的连接并导致它失败。

它改成这样:

SOCKET* clientsocket; 

那么它的话,只要你想做的事......

a.clientsocket = connectionSocket; 

变量“connectionSocket”是一个指针,然后热潮而来的炸药。当它没有被声明为一个变量时,拷贝构造函数被调用,并且你得到一个全新的套接字,而不是你之前使用的套接字。我认为这应该有所帮助?

相关问题