-2

we know that in a process, the number of threads has a limit, like around 1000.

If I want to create a tcp server based on multithreading,

each thread is responsible for one connection.

since there is 1 process, the number of threads is limited.

Then it means the number of concurrent connections is also limted.

Am my understanding correct or not?

if not, why?

thanks

user1944267
  • 1,557
  • 5
  • 20
  • 27
  • I'm not aware of the sort of fixed limit on thread numbers you're suggesting (system resources will impose a limit but its unlikey to be exactly 1000). That said, if you want to efficiently support a very large number of concurrent connections, you should consider using a smaller number of threads, each of which use `select` to wait on any one from a number of sockets. – simonc May 13 '13 at 09:25
  • what you meant is like, in each thread, create a int connfd[n]. and then for i in (1,n): connfd[i]=accept(). and then select(connfd[n])? are there sample source codes? thanks! – user1944267 May 13 '13 at 10:37
  • 1
    The old [C10K](http://www.kegel.com/c10k.html) page I linked has a discussion of I/O strategies and frameworks. – Useless May 13 '13 at 12:36
  • Thc limit is order(s) of magnitude more than 1000. – user207421 May 15 '13 at 00:02

3 Answers3

1

we know that in a process, the number of threads has a limit

True

If I want to create a tcp server based on multithreading,

TCP servers are based on TCP sockets - anything else is an implementation detail

each thread is responsible for one connection.

Don't do this. See discussions of the C10K problem for details, but essentially this is discouraged specifically because it scales so poorly.

since there is 1 process, the number of threads is limited. Then it means the number of concurrent connections is also limted.

Threads are a resource. All resources are limited. The sockets are also a limited resource. The only question is how well your server scales, and whether it's bottlenecked by unnecessary limits.

Am my understanding correct or not?

You're correct that system resources are intrinsically limited. You're mistaken in thinking that thread-per-client was ever a scalable, or sensible, design for servers. It's sometimes used for small server where ease-of-coding is more important than scalability.

Useless
  • 64,155
  • 6
  • 88
  • 132
0

Yes, there are resource limits on threads that are determined by your operating system and hardware.

Maximum number of threads per process in Linux?

You NEVER build a massively parallel server using a thread per connection. Use select() or poll() and non-blocking sockets. If you need to have more than one thread working on input (it really takes a lot before you can't do it in one process and you shouldn't be making blocking calls regardless), then create a worker pool sized around the number of processor cores you have available, and use those to process work as it becomes available.

More details on the worker pool concept. One thread can handle reading all the incoming network data off the network and tossing it somewhere. There is still additional work to do to process that data, however. For a simple chat server type application, no matter how many connections, one thread can probably be responsible for reading the data and processing the data.

However, if you have to do something like a bunch of physics calculations on each chunk of data received, one thread may not be able to handle all that math and stay current with incoming network data. In this case, have one thread take the data off the network and put it into a sychronized queue of data to be processed. Then have a handful or two of worker threads taking data off the queue and processing it in a thread-safe manner.

If you try to do this with thousands of threads, you will slow yourself down. They will all contend for system resources and you will actually proceed slower due to none of them getting the cpu cycles or RAM or CPU cache they want.

http://en.wikipedia.org/wiki/Thread_pool_pattern

Community
  • 1
  • 1
xaxxon
  • 19,189
  • 5
  • 50
  • 80
  • what is processor core? you meant number CPUs? then usually it is 1 or 2 – user1944267 May 13 '13 at 10:33
  • http://en.wikipedia.org/wiki/Multi-core_processor - basically I just meant a small number likely < 20 – xaxxon May 13 '13 at 11:13
  • OK, it is usually very small. like 2 or four. so, what you mean is: in each thread, create an socket descriptor array: int connfd[n]. and then for i in (1,n): connfd[i]=accept(). and then select(connfd[n])? are there sample source codes? – user1944267 May 13 '13 at 11:32
  • No, just do select in 1 thread. If you find yourself receiving more data than you can process in that one thread - meaning you start falling behind after processing the data and then looking for more, then take the data as you read it off (in one thread) into a synchronized queue where you have a pool of workers that then take the data and process it. But for 10k connections, you can still have 8 worker threads. – xaxxon May 13 '13 at 14:16
  • I updated the answer, since the comment was getting pretty long. – xaxxon May 13 '13 at 14:21
  • so there should be a lot of connfd=accept(). What he said is: in one thread, there are many accept() calls, and so there are many `connfd` at the same time? and then do `select()` on these many `connfd`, isn't it right? – misteryes May 13 '13 at 21:33
  • yeah, basically there's one thread in an infinite while loop looking for sockets to accept on, read from, or write to (selecting for write is something people often forget about, but is just as important). Technically accept is a read call, but it's special. But that's all it does. Normally you'd have a list or map of connected users and you'd throw whatever you read onto a buffer associated with that object. Once there is an amount of data that can be processed (remember you won't always get it all at once), then a worker thread picks it up (using thread locking mechanisms) and does work – xaxxon May 14 '13 at 03:27
0

Well, each thread is responsible for one connection. is a very subjective statement i suppose. because if a single thread is able to process your entire request with out any backlog left in the queue then a sigle thread can handle multiple requests.

There is always going to be a limit on everything in an operating system no matter how big it is be it threads, porcesses or connections or memory and really it takes more than a copuple of threads to process your entire requests a couple of queues may be along with tose processing threads.

asio_guy
  • 3,667
  • 2
  • 19
  • 35
  • The biggest reason people use this approach is usually because they want to make blocking calls while handling input. For low-performance, low-connection-count systems, this is a simple way to deal with connections without having to worry about how to make sure nothing ever blocks. Because of the blocking, no matter how simple the processing is, a single thread cannot handle the traffic - even if it's just two connections. – xaxxon May 14 '13 at 03:28