Week 11 #
Multiplexing Input and Output #
Handling multiple input/output clients with
select
andepoll
select
#
int select(int n, fd_set *read_fds, fd_set *write_fds, NULL, struct timeval *wait_timeout);
- Blocks until fds are ready
- Returns 0 if reaches the timeout, else returns positive count if some fds are ready
- Modifies the given
fd_set
s, set them again before the next call fd_set
: holds a set of file descriptorsn
: The highest fd you specify, + 1
fd_set
functions
#
void FD_ZERO(fd_set *s); // empties the set
void FD_SET(int fd, fd_set *s); // adds an fd to the set
void FD_CLR(int fd, fd_set *s); // deletes an fd
int FD_ISSET(int fd, fd_set *s); // queries if fd is in the set
Limitations #
- Max size for
fd_set
usually 1024 - Slow when using many file descriptors
epoll
#
Only available on Linux
int epoll_create1(int flags);
- Creates a new
epoll
instance - Returns the file descriptor of this instance (
epfd
) flags
: 0 orFD_CLOEXEC
- Instance only useful for other
epoll
functions
int epol_ctl(int epfd, int op, int another_epfd, struct epoll_event *ev);
- Sets what the
epoll
instance will wait for - Returns 0 if successful
op
:EPOLL_CTL_ADD
,EPOLL_CTL_DEL
,EPOLL_CTL_MOD
ev
: Events to wait for
int epoll_wait(int epfd, struct epoll_event *evs, int n, int timeout);
evs
: Array to recieve eventsn
: Length of events array- Returns count of ready file descriptors
struct epoll_event {
uint32_t events;
epoll_data_t data;
};
You can combine
events
using bitwise operatorsevents
:EPOLLIN
: Ready to readEPOLLOUT
: Ready to writeEPOLLONESHOT
: Monitor once onlyEPOLLET
: Notify whenever changes from not-ready to readyEPOLLHUP
: Other end of pipe/socket has closedEPOLLERR
: Error condition
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
- You store to this data when calling
epoll_ctl
- Stored data gets returned when you call
epoll_wait
- Usually store the fd, or a pointer to some
struct
to keep track of history