我想处理 300 到 400 个客户端连接,但我不想为每个客户端连接创建一个线程(或者创建 400 个线程有什么问题吗?)。
所以我读到我应该使用线程池来解决这个问题,但我无法理解线程池实际上是如何解决这个问题的。我的意思是在我对线程池的理解中,开始接任务的线程数量是有限的。但是一旦一个线程接受了一个recv()
任务,如果没有什么可读取的,它将立即阻塞!那么解决方案不应该是我应该有一种机制,让我在实际尝试阅读之前知道是否有东西要阅读吗?那么线程池究竟是如何解决我处理许多客户端连接的问题的呢?
编辑:将 read()
更改为 recv()
。
最佳答案
正如 user743414 已经指出的那样,多线程并不是一个好主意。但主要问题在于恕我直言,您阻塞了read
。如果有东西要读,你应该只使用 read 。使用 select
找出哪个套接字有东西要读取,并将其分派(dispatch)给线程池外的工作线程是通常的方法。
对于 Windows,您应该使用 WSASockets。
您在单个线程中使用select
。比您使用 select
的结果(它将告诉您需要在哪个套接字上执行操作)将连接分派(dispatch)到工作线程。
您写道您使用的是 Microsoft。拿 sample :
https://msdn.microsoft.com/en-us/library/windows/desktop/ms742219(v=vs.85).aspx
搜索代码
//-----------------------------------------
// If data has been received, echo the received data
// from DataBuf back to the client
iResult =
WSASend(AcceptSocket, &DataBuf, 1, &RecvBytes, Flags, &AcceptOverlapped, NULL);
if (iResult != 0) {
wprintf(L"WSASend failed with error = %d\n", WSAGetLastError());
}
你可以用你的线程池替换这部分(伪代码):
mythreadpool *thread=takeOrCreateThreadFromThreadPool();
thread->callWith(&DataBuf,&RecvBytes);
你会发现许多不同但很好的线程池实现,它们将使用类似的方法。
关于c++ - 线程池如何让我处理许多客户端连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28624275/