210 likes | 293 Views
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 server. Concurrent Server
E N D
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 server Concurrent Server select() listenfd Sockets fd1 fd2 fd3 fd4 fd5 C1 C2 C3 C4 C5 Clients
I/O Models • Blocking I/O • Non-blocking I/O • I/O multiplexing – select() • Signal driven I/O • Asynchronous I/O
Blocking I/O Application Operating system System call No datagram ready recvfrom() Wait for data datagram ready Process blocks Copy datagram Copy data to user Return ok Process datagram Copy complete
Non-Blocking I/O Application Operating system System call No datagram ready recvfrom() EWOULDBLOCK System call No datagram ready recvfrom() EWOULDBLOCK System call datagram ready recvfrom() Copy datagram Copy data to user Process blocks Return ok Process datagram Copy complete
I/O Multiplexing Application Operating system System call No datagram ready select() Wait for data Process blocks Return readable datagram ready System call recvfrom() Copy datagram Copy data to user Process blocks Return ok Process datagram Copy complete
Signal driven I/O Application Operating system Establish SIGIO Signal handler System call No datagram ready Wait for data Process continues Deliver SIGIO datagram ready Signal Handler System call recvfrom() Copy datagram Copy data to user Process blocks Return ok Copy complete Process datagram
Asynchronous I/O Application Operating system System call No datagram ready aio_read() return Wait for data datagram ready Process continues Copy datagram Copy data to user Return ok Copy complete Signal handler Process datagram
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.
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 *optval, /* 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)