Reputation: 621
I want to handle 300 to 400 client connections, but I do not want to create a thread for each client connection (or is there anything wrong in creating a 400 threads?).
so I have read that I should use a thread pool to fix this problem, but I am unable to understand how does a thread pool actually fix this problem. I mean in my understanding of a thread pool, there is a limited number of threads that start to take tasks. But once a thread takes a recv()
task it will immediately block if there is nothing to read! so isn't the solution should be that I should have a mechanism that allows me to know if there is something to be read before actually attempting to read it? So how exactly does a thread pool fix my problem of handling many client connections?
Edit: Changed read()
to recv()
.
Upvotes: 1
Views: 1225
Reputation: 4557
As user743414 already pointed out, to many threads are not a good idea. But the main problem lies IMHO in your blocking read
. You only should use read if there is something to read. Use select
to find out which socket has something to read and dispatch that to a worker thread out of the threadpool is the usual way.
With Windows you should use WSASockets.
You use select
in a single thread. Than you use the result of select
(which will tell you on which socket are action needed) to dispatch the connection to a worker thread.
You wrote that you use microsoft. Take the sample:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms742219(v=vs.85).aspx
search for the code
//-----------------------------------------
// 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());
}
you would replace this part with your threadpool like (pseudocode):
mythreadpool *thread=takeOrCreateThreadFromThreadPool();
thread->callWith(&DataBuf,&RecvBytes);
You will find many different but good threadpool implementation which will use methods like that.
Upvotes: 2
Reputation: 4750
The thread pool helps because you probably will not have all the 400 connections constantly sending and receiving data, so your app needs only a handful of threads to manage them all.
A single thread can monitor all the connections (using select
for instance) and as soon as select unlocks then it loops through all the sockets that need attention and pass them to the thread pool. If select
specified that a sockets has received data then read
will not block (and you can still set the timeout of read to 0)
Upvotes: 1
Reputation: 936
Creating 300 - 400 threads should work, but isn't the best solution. Context switch is here the keyword you have to search for. Context switches are expensive. Another problem with more threads is that each thread gets 1 MB stack memory, and that memory is limited. You could easily try this an check how many threads you can create.
With a threadpool you have one thread which receives a request an then give these request to your threadpool to work. So you wouldn't have a thread which blocks while waiting for reads. You threadpool is just working when there is something to read.
Another, better option would be on Windows I/O completion ports. Similar technics are also available on linux.
Upvotes: 2