Multithreaded udp server

2019-08-25 01:28发布

问题:

I'm new with threads and please if you can advice me. I have server that broadcast messages to clients. Then clients sends back replies to server. I want to handle every reply using seperate thread. Every reply will have mesage id and thread id. How can I fill some structure with this information from all threads and then read it

Also from my code, is it correctly to create thread in while or does it exist someway to create thread just if I get reply from client?

Did I start with correct understanding?

int main(){

    while(1){

        sendto on broadcast IP 
        pthread_create(&cln_thread, NULL, msg_processing, (void *) &arg))

   }
}

msg_processing () {

     recvfrom client msg with id of packet and thread id
     how to write those informations and then read them in main when program finish

}

Thank you

回答1:

Err.. no, just create ONE thread, once only, for receiving datagrams on one socket. In the thread function, receive the datagrams in a while(true) loop. Don't let this receive thread terminate and don't create any more receive threads. Continually creating/terminating/destroying threads is inefficient, dangerous, unnecessary, error-prone, difficult-to-debug and you should try very hard to not do it, ever.

Edit:

One receive thread only - but you don't have to do the processing there. Malloc a 64K buffer, receive data into it, push the buffer pointer onto a producer-consumer queue to a pool of threads that will do the processing, loop back and so malloc again to reseat the pointer and create another buffer for the next datagram. Free the *buffers in the pool threads after the processing is completed. The receive thread will be back waiting for datagrams quickly while the buffer processing runs concurrently.

If you find that the datagrams can arrive so rapidly that the processing cannot keep up, memory use will grow unchecked as more and more *buffers pile up in the queue. There are a couple ways round that. You can use a bounded queue that blocks if its capacity is reached. You could create x buffers at startup and store them on another producer-consumer 'pool queue' that the receive thread pops from, (instead of the malloc) - the processing pool threads can then push the 'used' *buffers back on to the pool queue for re-use. If the pool runs out, the receive thread will block on the pool until *buffers are returned.

I prefer the pooled-buffer approach since it caps memory-use across the whole system, avoids continual malloc/free with its fragmentation issues etc, avoids the more complex bounded queues, is easier to tweak, (the pool level is easy to change at runtime), and is easier to monitor/debug - I usually dump the pool level, (ie. queue count), to the display once a second with a timer.

In either case, datagrams may be lost but, if your system is overloaded such that data regularly arrives faster than it can possibly be processed, that's going to be the case anyway no matter how you design it.

One socket is fine, so why complicate matters? :)