int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
For the first parameter nfds
, here is what I get from wiki:
This is an integer one more than the maximum of any file descriptor in any of the sets. In other words, while adding file descriptors to each of the sets, you must calculate the maximum integer value of all of them, then increment this value by one, and then pass this as nfds.
I have a simple question:
If I have more than one socket to process, how should I set the first parameter of select
?
Should I set it with the largest socket number + 1?
If so, does it mean that the select
is listening all of file descriptors which is less than the largest socket number + 1?
For example, I have three sockets: 111, 222 and 333. If I set the first parameter as 334, does it mean that I'm listening all of file descriptors from 0 to 333?
Should I set it with the largest socket number + 1?
Yes!
If so, does it mean that the select is listening all of file descriptors which is less than the largest socket number + 1?
No, it only performs its operations on the fd_sets that are listed in readfds, writefds, and exceptfds
For example, I have three sockets: 111, 222 and 333. If I set the first parameter as 334, does it mean that I'm listening all of file descriptors from 0 to 333?
No, you are only doing $select$ on 111, 222 and 333.
Internally sys_select sets up 3 bitmaps which have a bit set to 1 for each of the three bitsets and then if any of these bits are set (which in turn corrospond the file descriptor operation) then the wait_key_set
operation is performed on it.
The reason for this interface is that in the kernel it devolves into a very predictable for-loop; making it quite safe to work with; rather than trying to do the calculation internally in the kernel.