【问题标题】:Handling threads in server application after clients disconnect客户端断开连接后处理服务器应用程序中的线程
【发布时间】:2015-10-07 05:22:03
【问题描述】:

我目前正在开发简单的 HTTP 服务器。我使用 C++11 中的 Winsock 和标准线程。对于每个连接(接受)的客户端,都会创建一个新线程。

std::map<SOCKET, std::thread> threads;

bool server_running = true;
while(server_running) {
    SOCKET client_socket;
    client_socket = accept(listen_socket, NULL, NULL);
    if(client_socket == INVALID_SOCKET) {
        // some error handling
    }
    threads[client_socket] = std::thread(clientHandler, client_socket);
}

clientHandler 函数大致如下所示:

while(1) {
    while(!all_data_received) {
        bytes_received = recv(client_socket, recvbuf, recvbuflen, 0);
        if(bytes_received > 0) {
            // do something
        } else {
            goto client_cleanup;
        }
    }
    // do something
}
client_cleanup: // we also get here when Connection: close was received
closesocket(client_socket);

这里我们来解决我的问题 - 如何处理所有已结束但尚未加入主线程并且对它们的引用仍然存在于 threads 映射中的线程?

最简单的解决方案可能是频繁地迭代threads(例如来自另一个线程?)并加入和删除返回的那些。

请分享您的专业知识。 :)

PS。是的,我知道 thread pool 模式。我没有在我的应用程序中使用它(无论好坏)。我正在寻找有关我当前架构的答案。

【问题讨论】:

  • 我不知道您的应用程序的规模,但众所周知,“每个客户端一个线程”服务器模型不可扩展。考虑在您的套接字上使用异步请求并忘记自己处理线程。毕竟,原始线程也被称为现代 goto(具有讽刺意味的是,您在示例中恰好使用了它)
  • 确切地说,仅用于学习目的。
  • 从一开始就学会正确地做事没有错。就个人而言,如果你学会了以一种方式制作服务器,我会觉得这是一种浪费,而一旦到了制作真正应用程序的时候,就必须学习一种全新的方式。当然,您仍然可以随心所欲。
  • @KABoissonneault 您所说的“套接字上的异步请求”是什么意思而忘记了自己处理线程?当当前一个没有数据要接收时,我应该只使用一个线程并转移到另一个套接字吗?
  • @KABoissonneault 你能推荐我比gotos 更好的错误处理解决方案吗?我不想重复自己。

标签: c++ multithreading c++11 server winsock


【解决方案1】:

简单的解决方案?启动线程后只需detach()。这意味着一旦线程终止,资源将被清理,您不需要保留std::map&lt;SOCKET, std::thread&gt; threads

std::thread(clientHandler, client_socket).detach();

否则,创建一个线程安全的 LIFO 队列,在清理期间您将套接字推送到该队列。

然后在主循环中,您交替检查accept 和该队列,当队列中有套接字时,您为队列中的每个套接字执行threads.erase(socket);

但是,如果您这样做,那么您不妨将 LIFO 放在另一个方向并使用线程池。

【讨论】:

  • 不知何故我认为detach-ing 线程不会是一个好的(干净的)解决方案。它有什么明显的缺点吗?
  • @Luke 只是不再引用线程对象了。但鉴于您只是将它们清理干净,这对您来说不是问题。
猜你喜欢
  • 2016-02-20
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多