Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using select() then read() vs a blocking read() loop

I am working on a multi-threaded server code where I create 2 threads which interact with a blocking TCP Socket after accept().

Thread #1 checks to see if there is a commands from msg queue and writes it to the socket. Thread #2 is just a simple while loop that calls read and then blocks if there is no data ready to be read.

However my colleague told me that I should not do a while loop with a read as it will waste CPU cycles (It's a blocking read, doesn't kernel put the thread to sleep?), that I should use select() system call then read the socket.

Am I incorrect with assuming the read thread? Which approach is better?

like image 485
hastartes Avatar asked Nov 10 '22 17:11

hastartes


1 Answers

You are correct that a thread does not consume CPU while blocked on I/O.

The select() syscall is a viable alternative, but its main use case is multiplexing I/O from / to multiple channels. In that case, it's not viable for one thread serve all the channels via blocking reads (or writes) because it would frequently be blocked waiting for data from one channel while a different one had data ready and waiting. On the other hand, you don't want to perform non-blocking reads in a loop, as that will waste CPU.

As for whether to prefer blocking on read() or blocking on select() (or poll()) for managing a single channel, that's a bit of an apples-to-oranges comparison, but if those are the choices then it's more straightforward to block on read(). That's what I would do. The apples-to-apples comparison would be more along the lines of multiple threads or child processes, each blocking on read()ing a different channel, vs. one thread of one process managing multiple channels with the help of select().

like image 76
John Bollinger Avatar answered Nov 14 '22 23:11

John Bollinger