I/O Multiplexing
What is I/O multiplexing?
• When an application needs to handle multiple I/O descriptors at the same time– E.g. file and socket descriptors, multiple socket
descriptors
• When I/O on any one descriptor can result in blocking
Non-forking concurrent serverConcurrent Server
select()
C1 C2 C3 C4 C5
listenfd
fd1 fd2 fd3 fd4 fd5Sockets
Clients
I/O Models
1. Blocking I/O
2. Non-blocking I/O
3. I/O multiplexing – select()
4. Signal driven I/O
5. Asynchronous I/O
Blocking I/O
recvfrom() No datagram ready
datagram ready
Copy datagram
Copy completeProcess datagram
System call
Application Operating system
Wait for data
Copy data to user
Return ok
Process blocks
Non-Blocking I/O
recvfrom() No datagram ready
datagram ready
Copy datagram
Copy completeProcess datagram
System call
Application Operating system
Copy data to user
Return ok
Process blocks
EWOULDBLOCK
recvfrom() No datagram readySystem call
EWOULDBLOCK
recvfrom() System call
I/O Multiplexing
select() No datagram ready
datagram ready
Copy datagram
Copy completeProcess datagram
System call
Application Operating system
Wait for data
Copy data to user
Return ok
Process blocks
Return readable
Process blocks
recvfrom() System call
Signal driven I/O
Establish SIGIOSignal handler No datagram ready
datagram ready
Copy datagram
Copy completeProcess datagram
System call
Application Operating system
Wait for data
Copy data to user
Return ok
Process blocks
Deliver SIGIO
Process continues
recvfrom() System callSignal Handler
Asynchronous I/O
aio_read() No datagram ready
datagram ready
Copy datagram
Copy completeSignal handlerProcess datagram
System call
Application Operating system
Wait for data
Copy data to user
Return ok
Process continues
return
select() call
• Allows a process to wait for an event to occur on any one of its descriptors.
• Types of event– ready for read– ready for write– Exception condition
select() call
int select(
int maxfdp1, /* max. fd + 1 */
fd_set *readfds, /* read ready? */
fd_set *writefds, /* write ready? */
fd_set *exceptfds, /* exceptions? */
struct timeval *timeout);
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
}
struct fd_set
• Set of descriptors that we want to wait on for events.
• Typically holds 256 descriptor states.
• Manipulation macros– void FD_ZERO(fd_set *fds) – void FD_SET (int fd, fd_set *fds)– void FD_CLR (int fd, fd_set *fds)– void FD_ISSET(int fd, fd_set *fds)
Non-forking Concurrent Server
fdset rdset, wrset;
int listenfd, connfd1, connfd2;
int maxfdp1;
………
Connection establishment etc.
………
/* initialize */
FD_ZERO(&rdset);
FD_ZERO(&wrset);
for( ;; ) {FD_SET(connfd1, &rdset);FD_SET(connfd2, &wrset);FD_SET(listenfd, &rdset);
maxfdp1 = max(connfd1, connfd2, listenfd) + 1;
/* wait for some event */Select(maxfdp1, &rdset, &wrset, NULL, NULL);
if( FD_ISSET(connfd1, &rdset) ) {Read data from connfd1…
} if( FD_ISSET(connfd2, &wrset) ) {
Write data to connfd2…
}if( FD_ISSET(listenfd, &rdset) {
Process a new connection…
}}
High resolution timer!
• Select can be used as a millisecond resolution timer.
select ( 0, NULL, NULL, NULL, &timeval)
• Usual sleep(…) call has resolution of seconds.
Socket Options
Managing socket options – 3 ways
• getsockopt() and setsockopt()• fcntl()• ioctl()
getsockopt() and setsockopt()
int getsockopt(int sockfd, int level, /* SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP etc */
int optname, /* option name */void *opt val, /* option value */socklen_t *optlen); /* data length of option*/
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
Some socket options
• SO_BROADCAST - enable socket for sending broadcast
• SO_KEEPALIVE – regularly probes on inactive TCP connection.
• SO_LINGER – linger till all data is sent before returning from close() on a TCP connection.
• SO_RCVBUF/ SO_SNDBUF – size of receive/send buffers on socket.
• SO_RCVTIMEO/SO_SNDTIMEO – place timeout on receive/send operation.
fcntl()
• int fcntl(int fd, int cmd, long arg);
• Miscellaneous file control operations– Non-blocking I/O (O_NONBLOCK, F_SETFL)
– Signal-driven I/O (O_ASYNC, F_SETFL)
– Set socket owner (F_SETOWN)
Top Related