1

我正在使用 Microsoft Windows WinSock API 的小型 http 服务器。

处理多个用户时是否需要应用多线程逻辑?

当前,当存在网络事件时,Windows 会发送一条消息,并且每条消息都携带(在 wParam 中)要在 send() 或 recv() 中使用的套接字。

当客户端 A 连接并请求几个文件时,Winsock 通常会创建一些套接字。然后我的服务器收到一条消息“将此文件发送到套接字 123”,然后“将该文件发送到套接字 456”

当另一个客户端连接时,它也会获得一些套接字,比如 789 和 654。

然后,我的服务器使用提供的套接字号响应发送数据的请求。它不必知道谁想要该文件,因为必须将正确的文件发送到正确的套接字。

我不知道在处理接受连接并将消息发送到我的程序时,Windows 本身是否使用多个线程。

所以我的问题是:

处理多个用户时是否需要应用多线程逻辑?如果是这样,我应该在什么时候创建一个线程?

4

2 回答 2

2

通常每个套接字使用一个线程。如果你正在接受连接,一个线程在循环中阻塞,等待传入的连接套接字。然后创建一个新线程并将这个套接字句柄传递给新线程来处理。当该连接关闭并完成时,只需让该线程终止(或加入)。这是线程服务器的基础。

在伪代码中...

loop {
  socket = accept();
  new ThreadHandler( socket )
}

使用单个线程处理多个套接字是很棘手的,主要是因为线程在写入时会阻塞(停止、等待),或者更常见的是从套接字读取。这不适合胆小的人。

于 2012-10-22T08:15:47.383 回答
0

对于大多数应用程序,使用多个线程来处理网络连接是没有意义的。我在回答这个问题时做了一个小文章。

当处理接收到的数据需要不可预测的 CPU 时间时,例如在数据库服务器中,或者当程序结构不允许异步处理请求时,多线程变得有用。

还有第三种选择,“工人池”。单个线程处理所有传入连接并反序列化传入请求,然后将工作项传递给一次处理一个项的线程池。

这样,简单地打开一个连接还不会消耗整个线程所需的资源,并且系统负载隐含地受到池中线程数的限制。

于 2012-10-22T08:35:10.720 回答