При проектировании средства ввода-вывода разработчики руководствуются двумя целями: достижением высокой эффективности и универсальности. Эффективность очень важна в силу того, что операции ввода-вывода часто способствуют возникновению "заторов" в компьютерной системе. Взгляните еще раз на рис. 11.1 — большинство устройств ввода-вывода работают по сравнению с основной памятью и процессором чрезвычайно медленно. Одним из способов решения этой проблемы является многозадачный режим, который позволяет процессору во время выполнения операций ввода-вывода одного процесса работать над выполнением других. Однако даже при наличии большого объема основной памяти в современных компьютерах зачастую будет возникать ситуация, когда операции ввода-вывода отстают от процессора. Для сохранения высокой загруженности процессора применяется подкачка, которая загружает в память готовые к выполнению процессы, но сама она представляет собой не что иное, как операцию ввода-вывода. Таким образом, основное внимание при создании операционной системы направлено на поиск эффективной схемы выполнения операций ввода-вывода. В силу своей важности дисковые операции ввода-вывода являются областью, заслуживающей особого внимания, и большая часть этой главы посвящена именно изучению производительности дисковых операций ввода-вывода.
Другой важной задачей является универсальность. Чтобы упростить работу с устройствами ввода-вывода и снизить вероятность возникновения ошибок, желательно иметь возможность одинакового управления различными устройствами. Это относится как к управлению устройствами ввода-вывода со стороны пользовательских процессов, так и со стороны операционной системы. Достичь реальной универсальности на практике, по сути, невозможно в силу огромного разнообразия характеристик устройств ввода-вывода, и самое большее, что можно сделать в подобной ситуации, — это применить модульный подход при разработке функций ввода-вывода. Такой подход позволяет скрыть детали устройства, так что пользовательские процессы обращаются к устройству только с высокоуровневыми вызовами: чтение и запись, открытие и закрытие, блокирование и разблокирование.