Thread: multiclient servers and threading..

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    108

    multiclient servers and threading..

    Hello,

    When designing a multi-client server system, is it necessary to have a separate thread for every single client connection? Or would you just have a single separate thread for all the client sockets, iterating through each of them listening for new updates..

    I'm new to multiclient servers (more precisely, C++ network programming), so I'm not sure..

    Thanks!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    A separate thread might be OK when the thread doesn't need to communicate with any other thread. As soon as that happens, you're into locks, semaphores, mutexes and race conditions which can get ugly in a hurry. Debugging a rare race condition is 1000% more complicated than your average bug. See Heisenbugs

    Plus threads come with a cost in terms of extra memory (each thread needs a stack), and processor time (the time to switch threads). Unless you guard against it, creating threads ad-nauseum becomes a DoS attack.
    Not that a single threaded solution needs to guard against accepting too many connections.

    A single thread and smart use of the select() call allows you to monitor multiple clients at the same time, and write nice simple code to deal with them without all the extra complexity.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Short answer: Yes.

    Longer answer: Depends on what the system does, the amount (and complexity) of processing each request requires, the response time expected by client applications, restrictions on memory usage, max number of threads, and many other factors.

    Some thoughts:
    If the processing of each request is really simple, then using a separate thread is overkill.
    On long and/or complex processing, using multiple threads will reduce the need to store/maintain state for multiple requests in differen stages of processing.
    Threads are also useful if you have to "wait" for stuff to happen when processing a request - e.g. you have to ask a database to retrieve some data, which may exceed the expectation of the waiting time for another request to initiate service [that is, if it takes 2 seconds to retrieve the data requested by one thread, another thread won't even start to be serviced until 2 seconds later if you don't have multiple threads].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    108
    Thanks for the help. I ended up implementing the whole thing using an extra thread (so two in total : the main app thread, and the networks thread) to handle network connections.

    The thing is, the network thread uses a select() call for both readers (the listening socket and sockets with incoming information) and the writers (connections with data to send).

    The problem is that when the select() is called, and there are no incoming data/connections nor data to be sent, it will block for the specified amount of time (1 second in my case), and this causes a 1 second latency in my program.. Because suppose that the program decides, just one milisecond after select() was called, that it wants to send data, it has to wait until the current select() finishes.

    So I was wondering, should I use two threads, one for incoming data/connections, and another for sending data? Can recv() and send() work in parallel of each other?

    I guess I could just put mutexes on each socket and they won't really have to work in parallel, but yeah, I guess I should ask.

    Also, because gethostbyname() blocks, I made my program create an extra thread for each connecting sockets, and the thread terminates when it's connected. This way connections aren't blocking. Is this a good way to do it, or did I miss something? (like a non-blocking gethostbyname())

    Sorry for the long question, I'm still a networks novice

  5. #5
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Actualy I disagree with matsp on the thread for complex don't thread for simple Issue. With sustained connections, even fi the processign per command is simple, You shoudl probably go with one thread per connection and use blockign connections. As the number of connections starts to increase, such that you have more active threads at any given time than you have processors in the system, you shoudl switch to some form of parallel serial processing ( sounds confusing heh?) . You want to avaoid having windows switch between too many threads, but you want to distribute the load over more thn a single thread to taek advantage of multi-core cpu's. So what you should do is have 1 thread per CPU processing the connections from a common pool, or have each connection assigned to a particular thread and do load balancing. I have no preference, it depends entirely on the application. If you are talking perhaps a few dozen connections, Id go with a common pool. If its a few thousand connections, Id go with load balancing, but there may be benefits in doing just the opposite in some situations.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    108
    I see.. thanks for the insight I don't know if my program will get to the ranges of above 30 connections

    With that said, the final (and I doubt it will change again) design is to have one thread to handle the common pool of incoming packets (from all sockets), one thread for packets to send (same, for all sockets), and one to accept connections.

    With that said, will three extra threads (the socket accept thread will be blocking all the time, waiting for connection, so its probably just two threads) impose a lot of extra processing costs? I'm guessing not, but in case there's this super obscure thing that I don't know of..

    btw, the program i'm making is a sort of a p2p thing, not sure what for yet though, just a holiday project

Popular pages Recent additions subscribe to a feed