C++传递对象给一个线程
我有一个关于一行为我不太明白问题: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;
}
};
匿名
是
可能是在正确的轨道上的东西超出范围,但我认为这是connectionSocket
。然而,当你说a.sendSocket()
不起作用时,你将不得不提供更多的细节。应用程序崩溃了吗?你有没有发现异常?应用程序是否继续工作,但sendSocket()
调用并未导致实际发送内容? 实际问题是什么?
应用程序不会崩溃,sendSocket()会在connectionSocket上发送文本消息。在第一个版本中,它确实发送了它,而在第二个版本中则没有。我想要做的是将一个对象传递给一个线程,包括套接字作为对象的公共变量。这样做的原因是我可以实例化并访问线程外部的对象。 – user912877 2012-04-16 18:37:46
它看起来像'connectionSocket'是一个指向实际套接字的指针,所以我建议您在将它传递给线程后验证它没有被销毁。你必须确保套接字的生命期足够长,以便线程可以使用它。 – Kiril 2012-04-16 18:40:56
“实际问题”是,除非我在线程中实例化对象,我显然不能写入a.clientsocket。我想实例化线程外的对象。它不会发送任何东西(我可以在客户端看到) – user912877 2012-04-16 18:50:22
我猜,在你的主线程中的CreateThread成功,然后再你的客户端变量,一个,超出了范围,因此被破坏。
我认为他的'connectionSocket'超出了范围。如果它是客户端,那么'a.testText()'不起作用。 – Kiril 2012-04-16 18:23:33
我正在传递&a通过CreateThread()和a.testText()在线程中工作。那么它是如何超出范围的? – user912877 2012-04-16 18:24:57
a.sendSocket()使用a.clientsocket ...不应该被保存在对象中? – user912877 2012-04-16 18:26:12
在第一种情况下,您传递一个connectionSocket,在第二种情况下,指向一个是Client类型的指针。也许你的意思是:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) clientThread, (LPVOID) a.clientsocket, 0, NULL);
在我看来,它是一个超出范围的对象。 SOCKET只是一个int HANDLE值并存储在一个成员中。当创建线程运行时,'a'在线程创建函数中超出范围,(或者在下一个accept()返回时损坏)。
Try:
Client a = new Client();
在分配多线程代码中的堆栈中的对象之前,请考虑15次,然后决定动态分配。
PS - @Anon先到那里 - 我没有注意到。
从客户端类
SOCKET clientsocket;
只要你传递上到一个线程,则SOCKET将不得不调用它的拷贝构造函数。这个拷贝构造函数可能是未定义的,或者它可能试图在同一个端口上打开一个新的连接并导致它失败。
它改成这样:
SOCKET* clientsocket;
那么它的话,只要你想做的事......
a.clientsocket = connectionSocket;
变量“connectionSocket”是一个指针,然后热潮而来的炸药。当它没有被声明为一个变量时,拷贝构造函数被调用,并且你得到一个全新的套接字,而不是你之前使用的套接字。我认为这应该有所帮助?
当你第二次调用'a.sendSocket()'时会发生什么?有某种例外或某种东西?应用程序崩溃了吗? – Kiril 2012-04-16 18:24:24
no不会崩溃,它只是不会向connectionSocket发送数据。 a.clientsSocket – user912877 2012-04-16 18:44:28
调试器中的'a.clientSocket'看起来如何?它仍然有效吗? – Kiril 2012-04-16 18:46:51