I've seen a few write-ups comparing select()
with poll()
or epoll()
, and I've seen many guides discussing the actual usage of select()
with multiple sockets.
However, what I can't seem to find is a comparison to a non-blocking recv()
call without select()
. In the event of only having 1 socket to read from and 1 socket to write to, is there any justification for using the select()
call? The recv()
method can be setup to not block and return an error (WSAEWOULDBLOCK
) when there is no data available, so why bother to call select()
when you have no other sockets to examine? Is the non-blocking recv()
call much slower?
From MSDN, the return value of connect(): On a blocking socket, the return value indicates success or failure of the connection attempt. With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR , and WSAGetLastError() will return WSAEWOULDBLOCK.
In blocking socket mode, a system call event halts the execution until an appropriate reply has been received. In non-blocking sockets, it continues to execute even if the system call has been invoked and deals with its reply appropriately later.
The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES).
If data is not available and socket is in nonblocking mode, recv() returns a -1 and sets the error code to EWOULDBLOCK. See fcntl() — Control Open Socket Descriptors or ioctl() — Control Socket for a description of how to set nonblocking mode.
You wouldn't want a non-blocking call to recv without some other means for waiting for data on the socket as you poll infinitely eating up cpu time.
If you have no other sockets to examine and nothing else to do in the same thread, a blocking call to read is likely to be the most efficient solution. Although in such a situation, considering the efficiency of this is like to be premature optimisation.
These kinds of considerations only tend to come into play as the socket count increases.
Nonblocking calls are only faster in the context of handling multiple sockets on a single thread.
If there is no data available, and you use non-blocking IO, recv()
will return immediately.
Then what should the program do ? You would need to call recv()
in a loop until data becomes available - this just uses CPU for pretty much no reason.
Spinning on recv()
and burning CPU in that manner is very undesirable; you'd rather want the process to wait until data becomes available and get woken up; that's what select()/poll()
and similar does.
And, sleep()
in the loop in order to not burn CPU is not a good solution either. You'd introduce high latency in the processing as the program will not be able to process data as soon as the data is available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With