1 i/o multiplexing we often need to be able to monitor multiple descriptors:we often need to be able...

15
1 I/O Multiplexing I/O Multiplexing We often need to be able to We often need to be able to monitor multiple descriptors: monitor multiple descriptors: a generic TCP client (like telnet) a generic TCP client (like telnet) need to be able to handle need to be able to handle unexpected situations, perhaps a unexpected situations, perhaps a server that shuts down without server that shuts down without warning. warning. A server that handles both TCP and A server that handles both TCP and UDP UDP

Upload: jeffrey-kelley

Post on 05-Jan-2016

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

1

I/O MultiplexingI/O Multiplexing

• We often need to be able to monitor We often need to be able to monitor multiple descriptors:multiple descriptors:– a generic TCP client (like telnet)a generic TCP client (like telnet)– need to be able to handle unexpected situations, need to be able to handle unexpected situations,

perhaps a server that shuts down without perhaps a server that shuts down without warning.warning.

– A server that handles both TCP and UDPA server that handles both TCP and UDP

Page 2: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

2

Example - generic TCP clientExample - generic TCP client

• Input from standard input should be sent to Input from standard input should be sent to a TCP socket.a TCP socket.

• Input from a TCP socket should be sent to Input from a TCP socket should be sent to standard output.standard output.

• How do we know when to check for input How do we know when to check for input from each source?from each source?

Page 3: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

3

Generic TCP ClientGeneric TCP Client

STDIN

STDOUT

TC

P S

OC

KE

T

Page 4: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

4

OptionsOptions

• Use nonblocking I/O.Use nonblocking I/O.– use fcntl() to set O_NONBLOCKuse fcntl() to set O_NONBLOCK

• Use alarm and signal handler to interrupt Use alarm and signal handler to interrupt slow system calls.slow system calls.

• Use multiple processes/threads.Use multiple processes/threads.

• Use functions that support checking of Use functions that support checking of multiple input sources at the same time.multiple input sources at the same time.

Page 5: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

5

Non blocking I/ONon blocking I/O

• use use fcntl()fcntl() to set to set O_NONBLOCKO_NONBLOCK::int flags;int flags;

flags = fcntl(sock,F_GETFL,0);flags = fcntl(sock,F_GETFL,0);

fcntl(sock,F_SETFL,flags | O_NONBLOCK);fcntl(sock,F_SETFL,flags | O_NONBLOCK);

• Now calls to Now calls to read()read() (and other system calls) (and other system calls) will return an error and set will return an error and set errnoerrno to to EWOULDBLOCKEWOULDBLOCK..

Page 6: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

6

while (! done) {while (! done) {

if ( (n=read(STDIN_FILENO,…)<0)) if ( (n=read(STDIN_FILENO,…)<0))

if (errno != EWOULDBLOCK)if (errno != EWOULDBLOCK)

/* ERROR *//* ERROR */

else write(tcpsock,…)else write(tcpsock,…)

if ( (n=read(tcpsock,…)<0)) if ( (n=read(tcpsock,…)<0))

if (errno != EWOULDBLOCK)if (errno != EWOULDBLOCK)

/* ERROR *//* ERROR */

else write(STDOUT_FILENO,…)else write(STDOUT_FILENO,…)

}}

Page 7: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

7

The problem with nonblocking I/OThe problem with nonblocking I/O

• Using blocking I/O allows the Operating Using blocking I/O allows the Operating System to put your program to sleep when System to put your program to sleep when nothing is happening (no input). Once input nothing is happening (no input). Once input arrives the OS will wake up your program arrives the OS will wake up your program and read() (or whatever) will return.and read() (or whatever) will return.

• With nonblocking I/O the process will chew With nonblocking I/O the process will chew up all available processor time!!!up all available processor time!!!

Page 8: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

8

Using alarmsUsing alarms

signal(SIGALRM, sig_alrm);signal(SIGALRM, sig_alrm);

alarm(MAX_TIME);alarm(MAX_TIME);

read(STDIN_FILENO,…);read(STDIN_FILENO,…);

......

signal(SIGALRM, sig_alrm);signal(SIGALRM, sig_alrm);

alarm(MAX_TIME);alarm(MAX_TIME);

read(tcpsock,…);read(tcpsock,…);

......

Page 9: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

9

Alarming ProblemAlarming Problem

• What will be the effect on response time ?What will be the effect on response time ?

• What is the ‘right’ value for MAX_TIME?What is the ‘right’ value for MAX_TIME?

Page 10: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

10

Select()Select()

• The select() system call allows us to use The select() system call allows us to use blocking I/O on a set of descriptors (file, blocking I/O on a set of descriptors (file, socket, …).socket, …).

• For example, we can ask select to notify us For example, we can ask select to notify us when data is available for reading on either when data is available for reading on either STDIN or a TCP socket. STDIN or a TCP socket.

Page 11: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

11

Select()Select()int select( int maxfd,int select( int maxfd,

fd_set *readset,fd_set *readset,

fd_set *writeset,fd_set *writeset,

fd_set *excepset,fd_set *excepset,

const struct timeval *timeout);const struct timeval *timeout);

maxfdmaxfd : : highest number assigned to a descriptor.highest number assigned to a descriptor.

weadsetweadset: : set of descriptors we want to read from.set of descriptors we want to read from.

writesetwriteset: : set of descriptors we want to write to.set of descriptors we want to write to.

excepsetexcepset: : set of descriptors to watch for exceptions.set of descriptors to watch for exceptions.

timeouttimeout: : maximum time select should waitmaximum time select should wait

Page 12: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

12

struct timevalstruct timeval

struct timeval {struct timeval {

long tv_usec;long tv_usec; /* seconds *//* seconds */

long tv_usec;long tv_usec; /* microseconds *//* microseconds */

}}

struct timeval max = {1,0};struct timeval max = {1,0};

Page 13: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

13

fd_setfd_set

• Implementation is not importantImplementation is not important

• Operations to use with fd_set:Operations to use with fd_set:

void FD_ZERO( fd_set *fdset);void FD_ZERO( fd_set *fdset);

void FD_SET( int fd, fd_set *fdset);void FD_SET( int fd, fd_set *fdset);

void FD_CLR( int fd, fd_set *fdset);void FD_CLR( int fd, fd_set *fdset);

int FD_ISSET( int fd, fd_set *fdset);int FD_ISSET( int fd, fd_set *fdset);

Page 14: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

14

Using Using select()select()

• Create fd_setCreate fd_set

• clear the whole thing with FD_ZEROclear the whole thing with FD_ZERO

• Add each descriptor you want to watch Add each descriptor you want to watch using FD_SET.using FD_SET.

• Call selectCall select

• when select returns, use FD_ISSET to see if when select returns, use FD_ISSET to see if I/O is possible on each descriptor.I/O is possible on each descriptor.

Page 15: 1 I/O Multiplexing We often need to be able to monitor multiple descriptors:We often need to be able to monitor multiple descriptors: –a generic TCP client

15

Proxy Web ServerProxy Web Server

• You don’t need to handle this situation for You don’t need to handle this situation for project 1 !!!!!!project 1 !!!!!!

• What if the server does not respond (is What if the server does not respond (is slow), the client gets tired of waiting and slow), the client gets tired of waiting and wants to make a new request?wants to make a new request?