C++将对象传递给线程

C++ passing an object to a thread

本文关键字:线程 对象 C++      更新时间:2023-10-16

我有一个关于我不太理解的行为的问题:

我有两种 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;
}
};

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

Anon 可能走在正确的轨道上,有些事情超出了范围,但我认为这是connectionSocket。但是,当您说a.sendSocket()不起作用时,您必须提供有关您意思的更多详细信息。应用程序会崩溃吗?你发现例外了吗?应用程序是否继续工作,但sendSocket()调用未导致实际发送内容?实际问题是什么?

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

CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE ) clientThread, ( LPVOID ) a.clientsocket, 0, NULL );
在我看来,

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

尝试:

客户端 a = 新客户端();

在多线程代码中在堆栈上分配对象之前,请三思而后行 15 次,然后决定动态分配。

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

来自客户端类

SOCKET clientsocket;

每当您将它传递到线程中时,SOCKET 都会在其上调用复制构造函数。此复制构造函数可能未定义,或者可能尝试在同一端口上打开新连接并导致其失败。

将其更改为:

SOCKET* clientsocket;

然后拥有它,以便无论何时您想做...

a.clientsocket = connectionSocket;

变量"connectionSocket"是一个指针,然后炸药轰动。当它未声明为变量时,将调用复制构造函数,您将获得一个比以前使用的套接字全新的套接字。我认为这应该有帮助吗?