Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
256 Chapter 16. Efficient I/O Scheduling Many applications are written to be interactive with one user. For these, it is a simple matter to be responsive to the whims of that one user. However, when you design server programs, each user of that server must receive immediate responses, as if there were only one user. This becomes impossible if your server is waiting for input from another user, within a system call. Consequently, a different design strategy is required when performing I/O with multiple clients. In this chapter, you will examine how to perform · Non-blocking I/O · I/O using select(2) · I/O using poll(2) Non-Blocking I/O A process is put to sleep when performing I/O for one or more of the following reasons: · A read request must wait for input data to arrive. · A write request must wait until previously written data has been written to the media. · A device must be opened, such as a modem terminal line waiting for a carrier or a FIFO waiting for a reader. · Mandatory locking is enabled on files, causing a wait for locking on a read or a write system call. Conceptually, the simplest solution to this problem is to not put the process to sleep. When the I/O cannot be completed, the system call returns an error indicating that it cannot succeed at this time. This is non-blocking I/O. Opening Files in Non-Blocking Mode One method of specifying to the UNIX kernel that you want to use non-blocking I/O is to open with the O_NONBLOCK flag: #include <fcntl.h> int open(const char *path, int flags, ...); where the flags argument is set to include O_NONBLOCK, to open in non-blocking mode. The O_NONBLOCK flag prevents the open(2) call from suspending the execution of the calling process if it must wait for some reason. This can happen, for example, when opening a terminal line that must have a modem carrier. With the O_NONBLOCK flag provided, the open call returns success immediately. Subsequently, after an open(2) has been accomplished with the O_NONBLOCK flag, other I/O op- erations are also subject to the non-blocking rule. This is explained further in upcoming sections. The following shows how a process can open its terminal line in non-blocking I/O mode: