Asynchronous I/O with
select, poll, epoll
SELECT
2
3 2
10
4 9
30 Select 35
7
35 9
5
What is select()?
Monitor multiple descriptors
How does it work?
Setup sets of sockets to monitor
select(): blocking until something happens
“Something” could be
Incoming connection: accept()
Clients sending data: read()
Pending data to send: write()
Timeout
How to you select
Monitor sockets with select()
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval
*timeout);
nfds
Max file descriptor + 1
fd_set : bit vector with FD_SETSIZE bits
readfds : bit vector of read descriptors to monitor
writefds : bit vector of write descriptors to monitor
exceptfds : set to NULL
timeout
how long to wait without activity before returning
What about bit vectors?
void FD_ZERO(fd_set *set);
clear out all bits
void FD_SET(int fd, fd_set *set);
set one bit
void FD_CLR(int fd, fd_set *set);
clear one bit
int FD_ISSET(int fd, fd_set *set);
test whether fd bit is set
Descriptor sets
struct fd_set
/* The fd_set member is required to be an array of longs. */
typedef long int __fd_mask;
/* Number of descriptors that can fit in an `fd_set'. */
#define __FD_SETSIZE 1024
#define __NFDBITS (8 * (int) sizeof (__fd_mask))
/* fd_set for select and pselect. */
typedef struct
{
/* XPG4.2 requires this member name. Otherwise avoid the name
from the global namespace. */
#ifdef __USE_XOPEN
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
} fd_set;
Limit
The only limit onthe number of clients that this
server can handle is the minimum of the two
values
FD_SETSIZE
The maximun number of descriptors allowed for this
process by the kernel.
Example
Demo
poll
Poll
int poll( struct pollfd *fds, nfds_t nfds, int timeout );
{fds}: pointer to array of
{ndfs}: number of items in the array.
{timeout}: milliseconds to wait.
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
Poll
When using select, the server maintains array
client[] and descriptor set rset. When using poll,
the server maintains array client of pollfd
structured
Demo
Epoll
Epoll details
int epoll_create(int size);
Create an epoll object and returns it file descriptor
int epoll_ctl(int epfd, int op, int fd, struct epoll_event
*event);
Controls (configures) whitch file descriptor are watches
by this object, and for which events
int epoll_wait(int epfd, struct epoll_event *events, int
maxevents, int timeout);
How it works?
epoll_wait is called by the server code.
It will return any fds that are ready (i.e. have data).
Two modes of operations
Edge triggered.
Level-triggered.
In edge triggered, process will be invoked only once per new arrival.
E.g. 2KB received, process reads 1KB only, next call will bock till further data
arrives even if 1KB already in.
In level triggered, process will be invoked till the buffer is empty.
E.g. 2KB received, 1KB red, next call won’t block but would return same
descriptor
Demo