Saturday, April 6, 2013

Multiplex I/O

Multiplex I/O allows application to block on multiple file descriptors and be notified when any one of them is ready for read or write.

select() sustem call implements synchronous multiplex I/O.  The call is passed with 3 watched file descriptor sets, with one of them for read, one for write and one for exception.  The set is ignore if NULL is passed.

When returns, the sets are modified to contain only the fd which is ready for I/O.  For example, if fd x and y is placed in the readfds when calling select(), and x is returned with the readfds, it means x is ready for reading without blocking and y is not.

select() accepts a parameter to indicate the amount of time to block before returning even if no fd is ready for I/O.

The watched fds list is manipluated by macro FD_SET and FD_CLR.  FD_ISSET is used to test if a particular fd is in the set and is used after the select() call.

Because select() has historically available in most UNIX comparing to other mechanism for subsecond resolution sleeping, it is used as a portablewya to sleep by providing an non-NULL time out but NULL for all 3 watched file sets.

pselect() system call is introduced in 4.2BSD and also adopted by POSIX.  There are 3 differences between pselect and select:

(1) pselect() uses the timespec structure instead of timeval structure. for its timeout parameter.  Timespec uses sec and nanosec and not microsec.  In practice, neither call provide reliable nanosec resolution.

(2) call to pselect() does not modify the timespec paramter and thus it does not need to reinitiatlized like timeval.

(3) pselect has an additional parameter sigmask.  pselect() with NULL as sigmask is same as select().  This parameter is intended to solve a race condition between waiting for the fd firing and signals.

poll() is a SystemV solution which solve a few deficiency of select().  The call uses a pollfd structure with each describe a file and a bitmask of events to look out for. the revent filed in the structure return the events that have fired (e.g. POLLIN for data to read, POLLPRI for reading urgent data, POLLOUT for writing, POLLWRBAND for writing priority data, POLLMSG for a SIGPOLL message is available)

POLLIN | POLLPRI is equivalent to select() read event.  POLLOUT | POLLWRBAND is equivalent to select() write event.  POLLIN is equivalent to POLLRDNORM + POLLRDBAND.  Linux provide a ppoll interface similar to pselect but ppoll is not a POSIX standard.

Comparing poll to select:
(1) poll does not need the programmer to specify the number of fd contained in the watched list
(2) poll is more efficient when monitoring a long list of fd because it passes in individual fd structure rather than a possibly sparse bitmask.
(3) select is more portable as it is available in most systems

No comments: