10

I need to repeatedly send and receive UDP datagrams to/from a socket. My idea was to spawn two threads, one responsible for sending and the other for receiving. The whole idea makes sense only if it is possible to one thread to wait on a blocking recv() and the other executing send() on the same socket at the same time.

I did some Googling and found this SO question: Are parallel calls to send/recv on the same socket valid? The accepted answer mentions that send() and recv() are thread-safe (whew…), but then proceeds with an alarming remark:

This doesn't necessarily mean that they'll be executed in parallel

Oops. Does this mean that if I implement my multithreaded idea, will I end up with the sending thread waiting for the receiving thread’s recv() to return before it actually starts sending its data? Bad.

It is ambiguous whether this accepted answer refers to two parallel send()’s only, or if the concern is real also for an attempt to parallely execute one send() and one recv(). Therefore:

Will a call to send() and a call to recv() on the same socket by two threads be executed parallely, or will one of these calls block until the other returns?

  • Why not set up a work-queue for the received packets that's processed by the other thread? Sharing file descriptors between threads is probably a bad idea. – tadman May 24 '17 at 19:57
  • 2
    1. They can... buy, IMHO: 2. It would be a poor design to do so. 3. Assuming only one thread is reading and the other is only sending, it might be a slightly better design, but it's still poor. 4. Blocking on `send` or `recv` isn't effective use of the CPU or your program's time. 4. You hardly need to threads for this, you can run a whole server with over 10K sockets on one thread. – Myst May 24 '17 at 19:59
  • @tadman Why is it a bad idea? The problem is that packets must be sent every 20ms, so I cannot wait until I receive something before I send anything. I thought designating a thread to perform the sending will make it easiest to keep this 20ms interval untouched by any unrelated processing overhead –  May 24 '17 at 19:59
  • 2
    Two native linux threads will run concurrently. Not necessarily in parallel, but concurrently. If one gets blocked, it won't affect the other one. – Petr Skocik May 24 '17 at 20:00
  • You could always prototype it as you're describing here and see if there's any issues, but be sure to slam it to the wall in terms of packet throughput to shake out any potential threading issues. – tadman May 24 '17 at 20:06

1 Answers1

4

Short answer: You should be ok to have separate threads for sending and receiving with the same socket handle.

A common scenario is a video conferencing application. You might want to have one thread recording from the microphone and sending audio out the udp port. Another thread receives packets on the same port and plays them back over the speakers.

If your protocol is more synchronous (i.e. request/response flow - in order to send, you first have to receive something first), then a single likely thread makes more sense from a design perspective.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • 1
    Can two separate threads send data on the same socket? Do I have to worry about the starvation of one thread in this? – y_159 Apr 08 '21 at 11:45