7.3. Blocking and Nonblocking I/OΒΆ
Some control over how the wait for I/O to complete is accommodated is
available to the programmer of user applications. Most I/O requests are
considered blocking requests, meaning that control does not return to
the application until the I/O is complete. The delayed from systems calls
such read()
and write()
can be quite long. Using systems calls that
block is sometimes called synchronous programming. In most cases, the
wait is not really a problem because the program can not do anything else
until the I/O is finished. However, in cases such as network programming
with multiple clients or with graphical user interface programming, the
program may wish to perform other activity as it continues to wait for more
data or input from users.
One solution for these situations is to use multiple threads so that one part of the program is not waiting for unrelated I/O to complete. Another alternative is to use asynchronous programming techniques with nonblocking system calls. An asynchronous call returns immediately, without waiting for the I/O to complete. The completion of the I/O is later communicated to the application either through the setting of some variable in the application or through the triggering of a signal or call-back routine that is executed outside the linear control flow of the application.
A good example of nonblocking behavior is the select()
system call for
network sockets. Using select()
, an application can monitor
several resources at the same time and can also poll for network activity
without blocking. The select()
system call identifies if data is pending
or not, then read()
or write()
may be used knowing that they will
complete immediately.
Note
Correct asynchronous programming can be complex, but since asynchronous programs have only one thread of execution, problems of Deadlock and Data Inconsistency are eliminated. For this reason, several programming frameworks exist that handle the difficult I/O issues making asynchronous programming much easier.
Asynchronous programming with call backs appears to be the most common approach for graphical user interface programming. It also has some advocates in the network programming realm, but multi-threaded programming is more often used with network programming.