gpt4 book ai didi

c++ - 在服务器应用程序的情况下,分离线程被认为是好的、中性的还是糟糕的设计

转载 作者:行者123 更新时间:2023-11-30 02:49:04 26 4
gpt4 key购买 nike

我最近使用在线指南使用 winsock 编写了一个简单的 tcp 服务器。然后我尝试在没有指南帮助的情况下对其进行多线程处理。经过一番挣扎后,我最终成功了,但只是通过分离线程。

我有一个无限循环,无论何时 accept() 返回一个 SOCKET,它都会创建一个 Handler,并调用 handle( )accept()SOCKET 结果传递给它。这是 handle() 函数,它从 accept() 调用中获取套接字并创建调用 processData 的线程:

void Handler::handle(SOCKET socket)
{
std::thread handlerThread([socket]{
processData(socket);
});
}

这是实际的 processData 函数,它是 Handler 中的静态函数:

void Handler::processData(SOCKET socket)
{
try
{
const int buffLength = 512;
char recvBuff[buffLength];
int recvResult = recv(socket, recvBuff, buffLength, 0);

if(recvResult > 0)
{
std::cout << recvBuff << std::endl;
}

closesocket(socket);
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}

此代码将在 recv() 调用上 abort(),代码 R6010 以某种方式逃避 try-catch。直到我将 handle 函数更改为:

void Handler::handle(SOCKET socket)
{
std::thread handlerThread([socket]{
processData(socket);
});

handlerThread.detach();
}

它能够通过 recv() 调用。

如果有人能解释为什么分离线程对 recv() 有影响,并且知道是否有更理想的设计模式,您不必分离工作线程 strong>,如果你愿意与我分享,我将不胜感激。

如果这太具体,也许可以就何时可以分离线程发表您的意见。

最佳答案

来自规范:

30.3.1.3 thread destructor [thread.thread.destr] ~thread(); If joinable(), calls std::terminate(). Otherwise, has no effects.

在第一种情况下,当 handle 返回时调用析构函数,因为您的线程对象在堆栈上。由于您的底层线程仍在运行并在 recv 函数中被阻止 std::terminate() 被调用。最终导致 abort() 调用。
当您分离线程时,您可以销毁 std::thread 对象,因为它不再是可连接的。

我个人尽量避免分离线程。因此,在您的情况下,我更喜欢线程池,或者您通过将线程对象存储在例如 vector 中来跟踪线程对象。

关于c++ - 在服务器应用程序的情况下,分离线程被认为是好的、中性的还是糟糕的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21548069/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com