Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does socket select() work?

As described in network programming books, select() monitors a set of file descriptors for reading. For example, here is part of code:

select(numfds, &read_fds, NULL, NULL, NULL);

Here numfds is maximum number of socket in read_fds + 1. Does it mean, that every "monitor" cycle select() watchs through all file descriptors of the process from 0 to numfds? I mean, if I have only two file descriptors to monitor(0 and 26), does select watch all descriptors from 0 to 26?

like image 806
Tural Gurbanov Avatar asked Feb 04 '13 22:02

Tural Gurbanov


2 Answers

select chooses which fds to watch based on the fd sets you pass in (readfds, writefds, exceptfds). The sets are typically implemented as bit vectors, so select will scan over the vector to see what fds are selected. As an optimization, you pass in the number of fds to scan up to so that select doesn't have to look at all fds up to FD_SETSIZE (which might not even be the same across compilation units).

select is a fairly expensive call because of the scanning and the necessity of resetting the sets after every call to select. On many platforms, select is just implemented on top of the poll system call, which offers a more efficient interface for waiting on file descriptors.

like image 186
nneonneo Avatar answered Sep 28 '22 00:09

nneonneo


Every monitor cycle means, whenever the operating system gets around to it essentially, it may choose to periodically check the descriptors or handle it via event or interrupts. When data is received on a socket file descriptor the descriptor file gets populated with data and the process that was waiting on it is informed. This doesn't always happen immediately as the process isn't woken immediately it is simply put back on the ready to run queue (since it was blocked by the select call). If the select call happens to fail (no data received in timeout) then a timer fires and puts the process back on the run queue.

Yes fd's in the FD_SET 0-26 are checked or monitored. This is just to put an upper bound on the search for file descriptors. IIRC this is because an fd_set type is implemented as a bitset internally since it is easier to specify indexes as this can save space. I may be wrong in the previous statement as I haven't visited that code in glibc in a while.

like image 25
Jesus Ramos Avatar answered Sep 27 '22 23:09

Jesus Ramos