How linux select work
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - synchronous I/O multiplexing
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become “ready” for some class of I/O operation (e.g., input possible).
The timeout argument specifies the interval that select() should block waiting for a file descriptor to become ready. The call will block until either:
a file descriptor becomes ready;
the call is interrupted by a signal handler; or
the timeout expires.
Example
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror(“select()”);
else if (retval)
printf(“Data is available now.\n”);
/* FD_ISSET(0, &rfds) will be true. */
else
printf(“No data within five seconds.\n”);
exit(EXIT_SUCCESS);
}Linux Implementation
Code is from linux 2.6.
This is the select system call entry.
The core logic
Allocate bit maps, all fds from 3 registered fd sets have a bit presented.
Loop and fetch each file, check its state, mark the bit if qualified. int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
Each file will be set state accordingly after I/O. The states are defined as:
Summary
select code checks every single file, and return results. We have to use FD_ISSET(FD, &rfds) to check which fd is actually ready.
If a lot of fds we are monitoring, the cost is very heavy.
Last updated
Was this helpful?