Search code examples
cunixfile-descriptorfcntlposix-select

Difference between select() and fcntl()


The way I understand it - we can use fctnl to mark a file descriptor as non-blocking, so whenever we call any blocking operation on that file descriptor, it would error and modify errno to indicate that the file descriptor isn't ready yet. The responsibility is on us to frequently poll the file descriptor and read or write whenever it is ready.

With select, we pass in three arrays(read, write and except) of file descriptors and then select polls the file descriptors for a given time interval, modifying the arrays to indicate which file descriptors are available for specified action. And select itself is a blocking operation.

Now my doubts are:

  1. Lets say I call select on an array file descriptors that needs to be read and it times out without detecting any events. Now if I call read on one of file descriptors, will it block or will it return E_WOULDBLOCK / E_AGAIN, even if I haven't used fcntl first?

  2. I call select with a timeout of 10s to check only on a single file descriptor. And the data is available to be read on the file descriptor almost immediately. In this case, will select still block for 10 seconds?


Solution

    1. If select() times out but you go to read a blocking file descriptor that is not ready, then you will block. The call to select() does not affect the behaviour of the file descriptor at all.

    2. If data is ready immediately, the select() call will return immediately. If the data is ready after 1 second, the select() call will return after 1 second. It will only return after 10 seconds if no data was ready during that time (or if the data arrived just fractionally before the timeout occurred).