Синхронный и асинхронный ввод-вывод. Термины: Ввод-вывод данных синхронный и асинхронный Что такое асинхронный ввод вывод

Ввод/вывод данных

Большая часть предыдущих статей посвящена вопросам оптимизации производительности вычислений. Мы видели множество примеров настройки процедуры сборки мусора, распараллеливания циклов и рекурсивных алгоритмов, и даже занимались оптимизацией алгоритмов, чтобы снизить накладные расходы во время выполнения.

Для некоторых приложений оптимизация вычислительных аспектов дает лишь незначительный выигрыш в производительности, потому что узким местом в них являются операции ввода/вывода, такие как передача данных по сети или доступ к диску. По своему опыту можем сказать, что значительная доля проблем производительности связана вовсе не с применением неоптимальных алгоритмов или чрезмерной нагрузкой на процессор, а с неэффективным использованием устройств ввода/вывода. Давайте рассмотрим две ситуации, когда оптимизация ввода/вывода может повысить общую производительность:

    Приложение может испытывать серьезные вычислительные перегрузки из-за неэффективности операций ввода/вывода, увеличивающих накладные расходы. Хуже того, перегрузка может быть настолько велика, что оказывается ограничивающим фактором, мешающим максимально использовать пропускную способность устройств ввода/вывода.

    Устройство ввода/вывода может быть задействовано недостаточно полно или его возможности могут растрачиваться впустую из-за применения неэффективных шаблонов программирования, как например, передача большого количества данных маленькими порциями или неиспользование всей пропускной способности канала.

В этой статье описываются общие понятия ввода/вывода и даются рекомендации по повышению производительности ввода/вывода любого типа. Эти рекомендации в равной степени применимы к сетевым приложениям, к процессам, интенсивно работающим с диском, и даже к программам, осуществляющим доступ к нестандартным, высокопроизводительным аппаратным устройствам.

Синхронный и асинхронный ввод/вывод

При выполнении в синхронном режиме, функции ввода/вывода Win32 API (например, ReadFile, WriteFile или DeviceloControl) блокируют выполнение программы до завершения операции. Хотя эта модель очень удобна в использовании, она не слишком эффективна. В промежутках времени между выполнением последовательных запросов на ввод/вывод устройство может простаивать, то есть, использоваться недостаточно полно.

Другая проблема синхронного режима состоит в том, что поток выполнения напрасно расходует время при выполнении любой конкурирующей операции ввода/вывода. Например, в серверном приложении, одновременно обслуживающем множество клиентов, может быть предусмотрено создание отдельного потока выполнения для каждого сеанса. Эти потоки, которые большую часть времени простаивают, понапрасну расходуют память и могут создавать ситуации пробуксовки потоков (thread thrashing) , когда множество потоков выполнения одновременно возобновляют работу по завершении ввода/вывода и начинают бороться за процессорное время, что приводит к увеличению переключений контекста в единицу времени и снижению масштабируемости.

Подсистема ввода/вывода Windows (включая драйверы устройств) внутренне действует в асинхронном режиме - программа может продолжать выполнение одновременно с операцией ввода/вывода. Практически все современные аппаратные устройства имеют асинхронную природу и не требуют постоянно опрашивать их, чтобы передать данные или определить момент завершения операции ввода/вывода.

Большинство устройств поддерживают возможность прямого доступа к памяти (Direct Memory Access, DMA) для передачи данных между устройством и ОЗУ компьютера, не требуя участия процессора в операции, и генерируют прерывание по завершении передачи данных. Синхронный режим ввода/вывода, который внутренне является асинхронным, поддерживается только на уровне приложений Windows.

В Win32 асинхронный ввод/вывод называется перекрывающимся вводом/выводом (overlapped I/O) , сравнение синхронного и перекрывающегося режимов ввода/вывода приводится на рисунке ниже:

Когда приложение производит асинхронный запрос на выполнение операции ввода/вывода, Windows либо выполняет эту операцию немедленно, либо возвращает код состояния, указывающий, что операция ожидает выполнения. После этого поток выполнения может запустить другие операции ввода/вывода или выполнить некоторые вычисления. Программист имеет несколько способов организовать прием извещений о завершении операций ввода/вывода:

    Событие Win32: операция, ожидающая это событие, будет выполнена по завершении ввода/вывода.

    Вызов пользовательской функции с помощью механизма асинхронного вызова процедур (Asynchronous Procedure Call, APC) : поток выполнения должен находиться в состоянии ожидания извещения (alertable wait).

    Прием извещений через порты завершения ввода/вывода (I/O Completion Ports, IOCP) : это обычно наиболее эффективный механизм. Мы подробно исследуем его далее.

Некоторые устройства ввода/вывода (например, файл, открытый в небуферизованном режиме) могут давать дополнительные выгоды, если приложение сумеет обеспечить постоянное присутствие небольшого количества ожидающих запросов ввода/вывода. Для этого рекомендуется предварительно произвести несколько запросов на выполнение операций ввода/вывода и для каждого выполненного запроса производить новый запрос. Это обеспечит инициализацию следующей операции драйвером устройства в самые кратчайшие сроки, не ожидая, пока приложение выполнит следующий запрос. Но не переусердствуйте с объемом передаваемых данных, потому что при этом будут потребляться ограниченные ресурсы памяти ядра.

Порты завершения ввода/вывода

Windows поддерживает эффективный механизм извещений о завершении асинхронных операций ввода/вывода под названием порт завершения ввода/вывода (I/O Completion Ports, IOCP). В приложениях для.NET он доступен посредством метода ThreadPool.BindHandle() . Этот механизм используется внутренними реализациями некоторых типов в.NET, выполняющих операции ввода/вывода: FileStream, Socket, SerialPort, HttpListener, PipeStream и некоторые каналы.NET Remoting.

Механизм IOCP, показанный на рисунке выше, связывается с несколькими дескрипторами ввода/вывода (сокетами, файлами и специализированными объектами драйверов устройств), открытыми в асинхронном режиме, и с определенным потоком выполнения. Как только операция ввода/вывода, связанная с таким дескриптором, завершится, Windows добавит извещение в соответствующий порт IOCP и передаст для обработки связанному с ним потоку выполнения.

Использование пула потоков, обслуживающих извещения и возобновляющих выполнение потоков, инициализировавших асинхронные операции ввода/вывода, снижает количество переключений контекста в единицу времени и увеличивает использование процессора. Неудивительно, что высокопроизводительные серверы, такие как Microsoft SQL Server, используют порты завершения ввода/вывода.

Порт завершения создается вызовом функции Win32 API CreateIoCompletionPort , которой передается максимальное значение параллелизма (количество потоков), ключ завершения и необязательный дескриптор объекта ввода/вывода. Ключ завершения - это определяемое пользователем значение, которое служит для идентификации различных дескрипторов ввода/вывода. С одним и тем же портом IOCP можно связать несколько дескрипторов, повторно вызывая функцию CreateIoCompletionPort и передавая ей дескриптор существующего порта завершения.

Чтобы установить связь с указанным портом IOCP, пользовательские потоки выполнения вызывают функцию GetCompletionStatus и ожидают ее завершения. В каждый конкретный момент времени поток выполнения может быть связан только с одним портом IOCP.

Вызов функции GetQueuedCompletionStatus блокирует выполнение потока, пока не появится соответствующее извещение (или не истечет предельное время ожидания), после чего возвращает информацию о завершившейся операции ввода/вывода, такую как количество переданных байтов, ключ завершения и структуру асинхронной операции ввода/вывода. Если в момент появления извещения все потоки, связанные с портом ввода/вывода, окажутся заняты (то есть, не останется потоков, ожидающих в вызове GetQueuedCompletionStatus), механизм IOCP создаст новый поток выполнения, вплоть до максимального значения параллелизма. Если поток вызвал GetQueuedCompletionStatus и очередь извещений не пуста, функция немедленно вернет управление, не блокируя поток в ядре операционной системы.

Механизм IOCP способен определить, что какой-то из «занятых» потоков фактически выполняет синхронный ввод/вывод, и запустить дополнительный поток, возможно превысив максимальное значение параллелизма. Извещения можно также посылать вручную, без выполнения ввода/вывода, вызовом функции PostQueuedCompletionStatus .

В следующем коде демонстрируется пример использования ThreadPool.BindHandle() с файловым дескриптором Win32:

Using System; using System.Threading; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; public class Extensions { internal static extern SafeFileHandle CreateFile(string lpFileName, EFileAccess dwDesiredAccess, EFileShare dwShareMode, IntPtr lpSecurityAttributes, ECreationDisposition dwCreationDisposition, EFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile); static unsafe extern bool WriteFile(SafeFileHandle hFile, byte lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, System.Threading.NativeOverlapped* lpOverlapped); enum EFileShare: uint { None = 0x00000000, Read = 0x00000001, Write = 0x00000002, Delete = 0x00000004 } enum ECreationDisposition: uint { New = 1, CreateAlways = 2, OpenExisting = 3, OpenAlways = 4, TruncateExisting = 5 } enum EFileAttributes: uint { // ... Некоторые флаги не показаны Normal = 0x00000080, Overlapped = 0x40000000, NoBuffering = 0x20000000, } enum EFileAccess: uint { // ... Некоторые флаги не показаны GenericRead = 0x80000000, GenericWrite = 0x40000000, } static long _numBytesWritten; // Тормоз для потока записи static AutoResetEvent _waterMarkFullEvent; static int _pendingIosCount; const int MaxPendingIos = 10; // Процедура завершения, вызывается потоками ввода/вывода static unsafe void WriteComplete(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP) { _numBytesWritten += numBytes; Overlapped ovl = Overlapped.Unpack(pOVERLAP); Overlapped.Free(pOVERLAP); // Известить поток записи, что количество ожидающих операций ввода/вывода // уменьшилось до допустимого предела if (Interlocked.Decrement(ref _pendingIosCount) = MaxPendingIos) { _waterMarkFullEvent.WaitOne(); } } } } }

Сначала рассмотрим метод TestIOCP. Здесь вызывается функция CreateFile(), которая является функцией механизма P/Invoke, используемой для открытия или создания файла или устройства. Для выполнения операций ввода/вывода в асинхронном режиме, необходимо передать функции флаг EFileAttributes.Overlapped. В случае успеха функция CreateFile() возвращает файловый дескриптор Win32, который мы связываем с портом завершения ввода/вывода вызовом ThreadPool.BindHandle(). Далее создается объект события, используемый для временного блокирования потока, инициировавшего операцию ввода/вывода, если таких операций оказывается слишком много (предел устанавливается константой MaxPendingIos).

Затем начинается цикл асинхронных операций записи. В каждой итерации создается буфер с данными для записи и структура Overlapped , содержащая смещение внутри файла (в данном примере запись всегда выполняется со смещением 0), дескриптор события, передаваемый по завершении операции (не используется механизмом IOCP), и необязательный пользовательский объект IAsyncResult , который можно использовать для передачи состояния в функцию завершения.

Далее вызывается метод Overlapped.Pack(), принимающий функцию завершения и буфер с данными. Он создает эквивалентную низкоуровневую структуру операции ввода/вывода, размещая ее в неуправляемой памяти, и закрепляет буфер с данными. Освобождение неуправляемой памяти, занимаемой низкоуровневой структурой, и открепление буфера должны выполняться вручную.

Если одновременно будет выполняться не слишком много операций ввода/вывода, мы вызываем WriteFile(), передавая ему указанную низкоуровневую структуру. В противном случае мы ждем, пока не появится событие, указывающее, что количество ожидающих операций стало меньше верхнего предела.

Функция завершения WriteComplete вызывается потоком из пула потоков завершения ввода/вывода, как только операция будет выполнена. Ей передается указатель на низкоуровневую структуру асинхронного ввода/вывода, которую можно распаковать и преобразовать в управляемую структуру Overlapped.

Подводя итоги, отметим, что при работе с высокопроизводительными устройствами ввода/вывода, применяйте асинхронные операции ввода/вывода с портами завершения, либо непосредственно, создавая и используя собственный порт завершения в неуправляемой библиотеке, либо связывая дескрипторы Win32 с портом завершения в.NET с помощью метода ThreadPool.BindHandle().

Пул потоков в.NET

Пул потоков выполнения в.NET можно с успехом использовать в самых разных целях, для достижения каждой из которых создаются потоки разных типов. При обсуждении параллельных вычислений ранее мы познакомились с прикладным программным интерфейсом пула потоков, где пользовались им для распараллеливания вычислительных задач. Однако пулы потоков можно использовать и для решения задач другого рода:

    Рабочие потоки могут обрабатывать асинхронные вызовы пользовательских делегатов (например, BeginInvoke или ThreadPool.QueueUserWorkItem).

    Потоки завершения ввода/вывода могут обслуживать уведомления, поступающие от глобального порта IOCP.

    Потоки ожидания могут обеспечивать ожидание наступления зарегистрированных событий, позволяя организовать ожидание сразу нескольких событий в одном потоке (с помощью WaitForMultipleObjects), вплоть до верхнего предела Windows (maximum wait objects = 64). Прием ожидания событий используется для организации асинхронного ввода/вывода без применение портов завершения.

    Потоки-таймеры, ожидающие, пока истекут сразу несколько таймеров.

    Потоки-регуляторы (gate threads) контролируют использование процессора потоками из пула, а также изменяют количество потоков (в установленных пределах) для достижения наивысшей производительности.

Имеется возможность инициировать операции ввода/вывода, которые кажутся асинхронными, но таковыми не являются. Например, вызов ThreadPool.QueueUserWorkItem делегата с последующим выполнением синхронной операции ввода/вывода не является по-настоящему асинхронной операцией и такое решение ничем не лучше выполнения той же операции в обычном потоке выполнения.

Копирование памяти

Нередко физическое устройство ввода/вывода возвращает буфер с данными, который копируется снова и снова, пока приложение не завершит его обработку. Подобное копирование может отнимать значительную долю вычислительной мощности процессора, поэтому его следует избегать, чтобы обеспечить максимальную пропускную способность. Далее мы рассмотрим несколько ситуаций, когда принято копировать данные, и познакомимся с приемами, позволяющими избежать этого.

Неуправляемая память

Работать с буфером, находящимся в неуправляемой памяти, в.NET значительно сложнее, чем с управляемым массивом byte, поэтому программисты, в поисках наиболее простого пути, часто копируют буфер в управляемую память.

Если применяемые вами функции или библиотеки позволяют явно указывать буфер в памяти или передавать им свою функцию обратного вызова для выделения буфера, распределите управляемый буфер и закрепите его в памяти, чтобы к нему можно было обращаться и по указателю, и по управляемой ссылке. Если буфер достаточно велик (> 85 000 байт), он будет создан в куче больших объектов (Large Object Heap) , поэтому старайтесь повторно использовать уже имеющиеся буферы. Если повторное использование буфера осложнено неопределенностью срока жизни объекта, применяйте пулы памяти.

В других случаях, когда функции или библиотеки сами выделяют память (неуправляемую) для буферов, вы можете обращаться к этой памяти непосредственно по указателю (из небезопасного кода) или используя классы-обертки, такие как UnmanagedMemoryStream и UnmanagedMemoryAccessor . Однако, если необходимо передать буфер некоторому коду, который оперирует только массивами byte или строковыми объектами, копирование может оказаться неизбежным.

Даже если вам не удается избежать копирования памяти и некоторые или большинство ваших данных фильтруется на ранних этапах, излишнего копирования можно избежать, проверив необходимость данных перед их копированием.

Экспортирование части буфера

Программисты иногда полагают, что массивы byte содержат только необходимые данные, от начала и до конца, вынуждая вызывающий код разбивать буфер (выделять память для нового массива byte и копировать только необходимые данные). Эту ситуацию часто можно наблюдать в реализациях стеков протоколов. Эквивалентный неуправляемый код, напротив, может принимать простой указатель, не зная даже, указывает ли он на начало фактического буфера или в его середину, и параметр длины буфера, позволяющий определить, где находится конец обрабатываемых данных.

Чтобы избежать ненужного копирования памяти, организуйте прием смещения и длины везде, где принимаете параметр byte. Используйте параметр длины вместо свойства Length массива, а значение смещения добавляйте к текущим индексам.

Чтение вразброс и запись со слиянием

Чтение вразброс и запись со слиянием - это возможность, поддерживаемая ОС Windows, выполнять чтение в несмежные области или записывать данные из несмежных областей, как если бы они занимали непрерывный участок памяти. Данная функциональность в Win32 API предоставляется в виде функций ReadFileScatter и WriteFileGather . Библиотека сокетов Windows также поддерживает возможность чтения вразброс и записи со слиянием, предоставляя собственные функции: WSASend, WSARecv и другие.

Чтение вразброс и запись со слиянием могут пригодиться в следующих ситуациях:

    Когда в каждом пакете имеется заголовок фиксированного размера, предшествующий фактическим данным. Чтение вразброс и запись со слиянием позволят вам избежать необходимости копировать заголовки всякий раз, когда потребуется получить непрерывный буфер.

    Когда желательно избавиться от лишних накладных расходов на обращения к системным вызовам, при выполнении ввода/вывода с несколькими буферами.

В сравнении с функциями ReadFileScatter и WriteFileGather, требующими, чтобы каждый буфер в точности соответствовал размеру одной страницы, а дескриптор был открыт в асинхронном и небуферизованном режиме (что является еще большим ограничением), функции чтения вразброс и записи со слиянием на основе сокетов выглядят более практичными, потому что не имеют этих ограничений. Фреймворк.NET Framework поддерживает чтение вразброс и запись со слиянием для сокетов посредством перегруженных методов Socket.Send() и Socket.Receive() , не экспортируя при этом универсальные функции чтения/записи.

Пример использования функций чтения вразброс и записи со слиянием можно найти в классе HttpWebRequest. Он объединяет HTTP-заголовки с фактическими данными, не прибегая к созданию непрерывного буфера для их хранения.

Файловый ввод/вывод

Обычно файловые операции ввода/вывода выполняются через кеш файловой системы, дающий некоторые выгоды с точки зрения производительности: кеширование недавно использованных данных, опережающее чтение (предварительное чтение данных с диска), отложенная запись (асинхронная запись на диск) и объединение операций записи маленьких порций данных. Подсказывая Windows ожидаемый шаблон доступа к файлам, можно получить дополнительный прирост производительности. Если ваше приложение выполняет асинхронный ввод/вывод и способно решать некоторые проблемы буферизации, тогда полный отказ от использования механизма кеширования может оказаться более эффективным решением.

Управление кешированием

Создавая или открывая файлы, программисты передают функции CreateFile флаги и атрибуты, часть из которых оказывает влияние на поведение механизма кеширования:

    Флаг FILE_FLAG_SEQUENTIAL_SCAN указывает, что обращение к файлу будет осуществляться последовательно, возможно с пропуском некоторых частей, а произвольный доступ маловероятен. В результате диспетчер кеша будет выполнять опережающее чтение с заглядыванием дальше обычного.

    Флаг FILE_FLAG_RANDOM_ACCESS указывает, что доступ к файлу будет осуществляться в произвольном порядке. В этом случае диспетчер кеша будет выполнять чтение с небольшим опережением, из-за снижения вероятности, что данные, прочитанные с опережением, действительно потребуются приложению.

    Флаг FILE_ATTRIBUTE_TEMPORARY указывает, что файл является временным, поэтому фактически операции записи на физический носитель (чтобы предотвратить потерю данных) можно отложить.

В.NET эти параметры поддерживаются (кроме последнего) с помощью перегруженного конструктора FileStream, принимающего параметр типа перечисления FileOptions.

Произвольный доступ отрицательно сказывается на производительности, особенно при работе с дисковыми устройствами, так как при этом возникает необходимость перемещать головки. В процессе развития технологий, пропускная способность дисков увеличивалась только за счет увеличения плотности хранения данных, но не за счет уменьшения задержек. Современные диски способны переупорядочивать выполнение запросов при произвольном доступе, чтобы уменьшить общее время, затрачиваемое на перемещение головок. Этот прием называется аппаратная установка очередности команд (Native Command Queuing, NCO) . Для большей эффективности этого приема контроллеру диска необходимо отправить сразу несколько запросов на ввод/вывод. Иными словами, если это возможно, старайтесь иметь сразу несколько ожидающих асинхронных запросов ввода/вывода.

Небуферизованный ввод/вывод

Операции небуферизованного ввода/вывода всегда выполняются без привлечения кеша. Такой подход имеет свои достоинства и недостатки. Как и в случае использования приема управления кешем, небуферизованный режим ввода/вывода включается с помощью параметра «флагов и атрибутов» в процессе создания файла, но.NET не обеспечивает доступ к этой возможности.

    Флаг FILE_FLAG_NO_BUFFERING отключает кеширование операций чтения и записи, но никак не влияет на кеширование, выполняемое контроллером диска. Это позволяет избежать копирования (из пользовательского буфера в кеш) и «загрязнения» кеша (заполнения кеша ненужными данными и вытеснение нужных). Однако небуферизованные операции чтения и записи должны придерживаться требований, касающихся выравнивания.

    Следующие параметры должны быть равны или кратны размеру дискового сектора: размер одной передачи, смещение в файле и адрес буфера в памяти. Обычно дисковый сектор имеет размер 512 байт. В новейших дисковых устройствах повышенной емкости размер сектора составляет 4096 байт, но они могут работать в режиме совместимости, эмулируя сектора размером 512 байт (за счет снижения производительности).

    Флаг FILE_FLAG_WRITE_THROUGH указывает диспетчеру кеша, что он должен сразу же выталкивать из кеша записываемые данные (если флаг FILE_FLAG_NO_BUFFERING не установлен) и сообщает контроллеру диска, что он должен выполнять запись на физический носитель немедленно, не сохраняя данные в промежуточном аппаратном кеше.

Опережающее чтение увеличивает производительность за счет более полного использования диска, даже когда приложение выполняет чтение в синхронном режиме с задержками между операциями. Правильное определение, какую часть файла приложение запросит в следующий раз, зависит от Windows. Отключая буферизацию, вы также отключаете опережающее чтение, и должны поддерживать высокую занятость дискового устройства выполняя несколько перекрывающихся операций ввода/вывода.

Запись с задержкой также увеличивает производительность приложений, выполняющих синхронные операции записи, создавая иллюзию, что запись на диск выполняется очень быстро. Приложение сможет улучшить использование процессора, из-за блокировок на более короткие интервалы времени. С отключенной буферизацией продолжительность операций записи будет равна полному интервалу времени, необходимому для завершения записи данных на диск. Поэтому применение асинхронного режима ввода/вывода при отключенной буферизации становится еще более важным.

Управление вводом/выводом.

блок-ориентированные устройства и байт-ориентированные

Основная идея

Ключевым принципом является независимость от устройств

· Обработка прерываний,

· Драйверы устройств,

Кажется очевидным, что возможны самые разнообразные прерывания по самым различным причинам. Поэтому с прерыванием связывают число - так называемый номер прерывания.

Этот номер однозначно соответствует тому или иному событию. Система умеет распознавать прерывания и при их возникновении запускает процедуру, соответствующую номеру прерывания.

Некоторые прерывания (первые пять по порядку номеров) зарезервированы для использования центральным процессором на случай каких-либо особых событий вроде попытки деления на нуль, переполнения и т. п. (это правда внутренние прерывания J).

Аппаратные прерывания всегда происходят асинхронно по отношению к выполняющимся программам. Кроме того, может возникнуть одновременно сразу несколько прерываний!

Для того чтобы система "не растерялась", решая какое прерывание обслуживать в первую очередь, существует специальная схема приоритетов. Каждому прерыванию назначается свой приоритет. Если происходит одновременно несколько прерываний, система отдает предпочтение самому высокоприоритетному, откладывая на время обработку остальных прерываний.

Система приоритетов реализована на двух микросхемах Intel 8259 (или аналогичных). Каждая микросхема является контроллером прерывания и обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.

Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15.


24. Управление вводом/выводом. Синхронный и асинхронный ввод/вывод.

Одной из главных функций ОС является управление всеми устройствами ввода-вывода компьютера. ОС должна передавать устройствам команды, перехватывать прерывания и обрабатывать ошибки; она также должна обеспечивать интерфейс между устройствами и остальной частью системы. В целях развития интерфейс должен быть одинаковым для всех типов устройств (независимость от устройств). Подробнее про управление в/в вопрос 23.

Принципы защиты

Поскольку ОС UNIX с самого своего зарождения задумывалась как многопользовательская операционная система, в ней всегда была актуальна проблема авторизации доступа различных пользователей к файлам файловой системы. Под авторизацией доступа мы понимаем действия системы, которые допускают или не допускают доступ данного пользователя к данному файлу в зависимости от прав доступа пользователя и ограничений доступа, установленных для файла. Схема авторизации доступа, примененная в ОС UNIX, настолько проста и удобна и одновременно настолько мощна, что стала фактическим стандартом современных операционных систем (не претендующих на качества систем с многоуровневой защитой).

Защита файлов

Как принято в многопользовательской операционной системе, в UNIX поддерживается единообразный механизм контроля доступа к файлам и справочникам файловой системы. Любой процесс может получить доступ к некоторому файлу в том и только в том случае, если права доступа, описанные при файле, соответствуют возможностям данного процесса.

Защита файлов от несанкционированного доступа в ОС UNIX основывается на трех фактах. Во-первых, с любым процессом, создающим файл (или справочник), ассоциирован некоторый уникальный в системе идентификатор пользователя (UID - User Identifier ), который в дальнейшем можно трактовать как идентификатор владельца вновь созданного файла. Во-вторых, с каждый процессом, пытающимся получить некоторый доступ к файлу, связана пара идентификаторов - текущие идентификаторы пользователя и его группы. В-третьих, каждому файлу однозначно соответствует его описатель - i-узел.

На последнем факте стоит остановиться более подробно. Важно понимать, что имена файлов и файлы как таковые - это не одно и то же. В частности, при наличии нескольких жестких связей с одним файлом несколько имен файла реально представляют один и тот же файл и ассоциированы с одним и тем же i-узлом. Любому используемому в файловой системе i-узлу всегда однозначно соответствует один и только один файл. I-узел содержит достаточно много разнообразной информации (большая ее часть доступна пользователям через системные вызовы stat и fstat), и среди этой информации находится часть, позволяющая файловой системе оценить правомощность доступа данного процесса к данному файлу в требуемом режиме.

Общие принципы защиты одинаковы для всех существующих вариантов системы: Информация i-узла включает UID и GID текущего владельца файла (немедленно после создания файла идентификаторы его текущего владельца устанавливаются соответствующими действующим идентификатором процесса-создателя, но в дальнейшем могут быть изменены системными вызовами chown и chgrp). Кроме того, в i-узле файла хранится шкала, в которой отмечено, что может делать с файлом пользователь - его владелец, что могут делать с файлом пользователи, входящие в ту же группу пользователей, что и владелец, и что могут делать с файлом остальные пользователи. Мелкие детали реализации в разных вариантах системы различаются.

28. Управление доступом к файлам в ОС Windows NT. Списки прав доступа.

Система управления доступом в ОС Windows NT отличается высокой степенью гибкости, которая достигается за счет большого разнообразия субъектов и объектов доступа, а также детализации операций доступа.

Контроль доступа к файлам

Для разделяемых ресурсов в Windows NT применяется общая модель объекта, который содержит такие характеристики безопасности, как набор допустимых операций, идентификатор владельца, список управления доступом.

Объекты в Windows NT создаются для любых ресурсов в том случае, когда они являются или становятся разделяемыми - файлов, каталогов, устройств, секций памяти, процессов. Характеристики объектов в Windows NT делятся на две части - общую часть, состав которой не зависит от типа объекта, и индивидуальную, определяемую типом объекта.
Все объекты хранятся в древовидных иерархических структурах, элементами которых являются объекты-ветви (каталоги) и объекты-листья (файлы). Для объектов файловой системы такая схема отношений является прямым отражением иерархии каталогов и файлов. Для объектов других типов иерархическая схема отношений имеет свое содержание, например, для процессов она отражает связи родитель-потомок, а для устройств отражает принадлежность к определенному типу устройств и связи устройства с другими устройствами, например SCSI-контроллера с дисками.

Проверка прав доступа для объектов любого типа выполняется централизованно с помощью монитора безопасности (Security Reference Monitor), работающего в привилегированном режиме.

Для системы безопасности Windows NT характерно наличие большого количества различных предопределенных (встроенных) субъектов доступа - как отдельных пользователей, так и групп. Так, в системе всегда имеются такие пользователи, как Adininistrator, System и Guest, а также группы Users, Adiniiiistrators, Account Operators, Server Operators, Everyone и другие. Смысл этих встроенных пользователей и групп состоит в том, что они наделены некоторыми правами, облегчая администратору работу по созданию эффективной системы разграничения доступа. При добавлении нового пользователя администратору остается только решить, к какой группе или группам отнести этого пользователя. Конечно, администратор может создавать новые группы, а также добавлять права к встроенным группам для реализации собственной политики безопасности, но во многих случаях встроенных групп оказывается вполне достаточно.

Windows NT поддерживает три класса операций доступа, которые отличаются типом субъектов и объектов, участвующих в этих операциях.

□ Разрешения (permissions) - это множество операций, которые могут быть определены для субъектов всех типов по отношению к объектам любого типа: файлам, каталогам, принтерам, секциям памяти и т. д. Разрешения по своему назначению соответствуют правам доступа к файлам и каталогам в QC UNIX.

□ Права (user rights) - определяются для субъектов типа группа на выполнение некоторых системных операций: установку системного времени, архивирование файлов, выключение компьютера и т. п. В этих операциях участвует особый объект доступа - операционная система в целом.

В основном именно права, а не разрешения отличают одну встроенную группу пользователей от другой. Некоторые права у встроенной группы являются также встроенными - их у данной группы нельзя удалить. Остальные права встроенной группы можно удалять (или добавлять из общего списка прав).

□ Возможности пользователей (user abilities) определяются для отдельных пользователей на выполнение действий, связанных с формированием их операционной среды, например изменение состава главного меню программ, возможность пользоваться пунктом меню Run (выполнить) и т. п. За счет уменьшения набора возможностей (которые по умолчанию доступны пользователю) администратор может заставить пользователя работать с той операционной средой, которую администратор считает наиболее подходящей и ограждающей пользователя от возможных ошибок.

Права и разрешения, данные группе, автоматически предоставляются ее членам, позволяя администратору рассматривать большое количество пользователей как единицу учетной информации и минимизировать свои действия.

При входе пользователя в систему для него создается так называемый токен доступа (access token), включающий идентификатор пользователя и идентификаторы всех групп, в которые входит пользователь. В токене также имеются: список управления доступом (ACL) по умолчанию, Который состоит из разрешений и применяется к создаваемым процессом объектам; список прав пользователя на выполнение системных действий.

Все объекты, включая файлы, потоки, события, даже токены доступа, когда они создаются, снабжаются дескриптором безопасности. Дескриптор безопасности содержит список управления доступом - ACL.

Файловый дескриптор - неотрицательное целое число, присваиваемое ОС открытому процессом файлу.

ACL (англ. Access Control List - список контроля доступа, по-английски произносится «экл») - определяет, кто или что может получать доступ к конкретному объекту, и какие именно операции разрешено или запрещено этому субъекту проводить над объектом.

Списки контроля доступа являются основой систем с избирательным управлением доступом. (Wiki )

Владелец объекта, обычно пользователь, который его создал, обладает правом избирательного управления доступом к объекту и может изменять ACL объекта, чтобы позволить или не позволить другим осуществлять доступ к объекту. Встроенный администратор Windows NT в отличие от суперпользователя UNIX, может не иметь некоторых разрешений на доступ к объекту. Для реализации этой возможности идентификаторы администратора и группы администраторов могут входить в ACL, как и идентификаторы рядовых пользователей. Однако администратор все же имеет возможность выполнить любые операции с любыми объектами, так как он всегда может стать владельцем объекта, а затем уже как владелец получить полный набор разрешений. Однако вернуть владение предыдущему владельцу объекта администратор не может, поэтому пользователь всегда может узнать о том, что с его файлом или принтером работал администратор.

При запросе процессом некоторой операции доступа к объекту в Windows NT управление всегда передается монитору безопасности, который сравнивает- иден-тификаторы пользователя и групп пользователей из токена доступа с иденти-фикаторами, хранящимися в элементах ACL объекта. В отличие от UNIX в эле-ментах ACL Windows NT могут существовать как списки разрешенных, так я списки запрещенных для пользователя операций.

В Windows NT однозначно определены правила, по которым вновь создаваемому объекту назначается список ACL. Если вызывающий код во время создания объекта явно задает все права доступа к вновь создаваемому объекту, то система безопасности приписывает этот ACL объекту.

Если же вызывающий код не снабжает объект списком ACL, а объект имеет имя, то применяется принцип наследования разрешений. Система безопасности про-сматривает ACL того каталога объектов, в котором хранится имя нового объекта. Некоторые из входов ACL каталога объектов могут быть помечены как насле-дуемые. Это означает, что они могут быть приписаны новым объектам, создаваемым в этом каталоге.

В том случае, когда процесс не задал явно список ACL для создаваемого объекта и объект-каталог не имеет наследуемых элементов ACL, используется список ACL по умолчанию из токена доступа процесса.


29. Язык программирования Java. Виртуальная машина Java. Технология Java.

Java - объектно-ориентированный язык программирования, разработанный компанией Sun Microsystems. Приложения Java обычно компилируются в специальный байт-код, поэтому они могут работать на любой виртуальной Java-машине (JVM) независимо от компьютерной архитектуры. Программы на Java транслируются в байт-код, выполняемый виртуальной машиной Java (JVM ) - программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор, но с тем отличием, что байтовый код, в отличие от текста, обрабатывается значительно быстрее.

Достоинство подобного способа выполнения программ - в полной независимости байт-кода от операционной системы и оборудования, что позволяет выполнять Java-приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной . Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание.

Часто к недостаткам концепции виртуальной машины относят то, что исполнение байт-кода виртуальной машиной может снижать производительность программ и алгоритмов, реализованных на языке Java.

Java Virtual Machine (сокращенно Java VM, JVM ) - виртуальная машина Java - основная часть исполняющей системы Java, так называемой Java Runtime Environment (JRE). Виртуальная машина Java интерпретирует и исполняет байт-код Java, предварительно созданный из исходного текста Java-программы компилятором Java (javac). JVM может также использоваться для выполнения программ, написанных на других языках программирования. Например, исходный код на языке Ada может быть откомпилирован в байт-код Java, который затем может выполниться с помощью JVM.

JVM является ключевым компонентом платформы Java. Так как виртуальные машины Java доступны для многих аппаратных и программных платформ, Java может рассматриваться и как связующее программное обеспечение, и как самостоятельная платформа, отсюда принцип «написано однажды, запускается везде» (write once, run anywhere). Использование одного байт-кода для многих платформ позволяет описать Java как «скомпилировано однажды, запускается везде» (compile once, run anywhere).

Среда исполнения

Программы, предназначенные для запуска на JVM должны быть скомпилированы в стандартизированном переносимом двоичном формате, который обычно представляется в виде файлов.class. Программа может состоять из множества классов, размещенных в различных файлах. Для облегчения размещения больших программ, часть файлов вида.class могут быть упакованы вместе в так называемый.jar файл (сокращение от Java Archive).

Виртуальная машина JVM исполняет файлы.class или.jar, эмулируя инструкции, написанные для JVM, путем интерпретирования или использования just-in-time компилятора (JIT), такого, как HotSpot от Sun microsystems. В наши дни JIT компиляция используется в большинстве JVM в целях достижения большей скорости.

Как и большинство виртуальных машин, Java Virtual Machine имеет stack-ориентированную архитектуру, свойственную микроконтроллерам и микропроцессорам.

JVM, которая является экземпляром JRE (Java Runtime Environment), вступает в действие при исполнении программ Java. После завершения исполнения, этот экземпляр удаляется сборщиком мусора. JIT является частью виртуальной машины Java, которая используется для ускорения времени выполнения приложений. JIT одновременно компилирует части байт-кода, которые имеют аналогичную функциональность, и, следовательно, уменьшает количество времени, необходимого для компиляции.

j2se (java 2 standard edition) – стандартная библиотека включает в себя:

GUI, NET, Database…


30. Платформа.NET. Основные идеи и положения. Языки программирования.NET.

.NET Framework - программная технология от компании Microsoft, предназначенная для создания обычных программ и веб-приложений.

Одной из основных идей Microsoft .NET является совместимость различных служб, написанных на разных языках. Например, служба, написанная на C++ для Microsoft .NET, может обратиться к методу класса из библиотеки, написанной на Delphi; на C# можно написать класс, наследованный от класса, написанного на Visual Basic .NET, а исключение, созданное методом, написанным на C#, может быть перехвачено и обработано в Delphi. Каждая библиотека (сборка) в.NET имеет сведения о своей версии, что позволяет устранить возможные конфликты между разными версиями сборок.

Приложения также можно разрабатывать в текстовом редакторе и использовать консольный компилятор.

Подобно технологии Java, среда разработки.NET создаёт байт-код, предназначенный для исполнения виртуальной машиной. Входной язык этой машины в.NET называется MSIL (Microsoft Intermediate Language), или CIL (Common Intermediate Language, более поздний вариант), или просто IL.

Применение байт-кода позволяет получить кроссплатформенность на уровне скомпилированного проекта (в терминах.NET: сборка ), а не только на уровне исходного текста, как, например, в С. Перед запуском сборки в среде исполнения CLR байт-код преобразуется встроенным в среду JIT-компилятором (just in time, компиляция на лету) в машинные коды целевого процессора. Также существует возможность скомпилировать сборку в родной (native) код для выбранной платформы с помощью поставляемой вместе с.NET Framework утилиты NGen.exe.

В ходе выполнения процедуры трансляции исходный текст программы (написанный на SML, C#, Visual Basic, C++ или любом другом языке программирования, который поддерживается.NET) преобразуется компилятором в так называемую сборку (assembly) и сохраняется в виде файла динамически присоединяемой библиотеки (Dynamically Linked Library, DLL) или исполняемого файла (Executable, EXE).

Естественно, что для каждого компилятора (будь то компилятор языка C#, csc.exe или Visual Basic, vbc.exe) средой времени выполнения производится необходимое отображение используемых типов в типы CTS, а программного кода – в код "абстрактной машины" .NET – MSIL (Microsoft Intermediate Language).

В итоге программный проект формируется в виде сборки – самодостаточного компонента для развертывания, тиражирования и повторного использования. Сборка идентифицируется цифровой подписью автора и уникальным номером версии.

Встроенные языки программирования (поставляются вместе с.NET Framework):

C#; J#; VB.NET; JScript .NET; C++/CLI - новая версия C++ (Managed).


31. Функциональные компоненты ОС. Управление файлами

Функциональные компоненты ОС:

Функции операционной системы автономного компьютера обычно группируются либо в соответствии с типами локальных ресурсов, которыми управляет ОС, либо в соответствии со специфическими задачами, применимыми ко всем ресурсам. Иногда такие группы функций называют подсистемами. Наиболее важными подсистемами управления ресурсами являются подсистемы управления процессами, памятью, файлами и внешними устройствами, а подсистемами, общими для всех ресурсов, являются подсистемы пользовательского интерфейса, защиты данных и администрирования.

Управление файлами:

Способность ОС к «экранированию» сложностей реальной аппаратуры очень ярко проявляется в одной из основных подсистем ОС - файловой системе.

Файловая система связывает носитель информации с одной стороны и API (интерфейс прикладного программирования) для доступа к файлам - с другой. Когда прикладная программа обращается к файлу, она не имеет никакого представления о том, каким образом расположена информация в конкретном файле, так же, как и на каком физическом типе носителя (CD, жёстком диске, магнитной ленте или блоке флеш-памяти) он записан. Всё, что знает программа - это имя файла, его размер и атрибуты. Эти данные она получает от драйвера файловой системы. Именно файловая система устанавливает, где и как будет записан файл на физическом носителе (например, жёстком диске).

С точки зрения операционной системы, весь диск представляет собой набор кластеров размером от 512 байт и выше. Драйверы файловой системы организуют кластеры в файлы и каталоги (реально являющиеся файлами, содержащими список файлов в этом каталоге). Эти же драйверы отслеживают, какие из кластеров в настоящее время используются, какие свободны, какие помечены как неисправные.

Однако файловая система не обязательно напрямую связана с физическим носителем информации. Существуют виртуальные файловые системы, а также сетевые файловые системы, которые являются лишь способом доступа к файлам, находящимся на удалённом компьютере.

В простейшем случае все файлы на данном диске хранятся в одном каталоге. Такая одноуровневая схема использовалась в CP/M и в первой версии MS-DOS 1.0. Иерархическая файловая система со вложенными друг в друга каталогами впервые появилась в Multics, затем в UNIX.

Каталоги на разных дисках могут образовывать несколько отдельных деревьев, как в DOS/Windows, или же объединяться в одно дерево, общее для всех дисков, как в UNIX-подобных системах.

На самом деле, в DOS/Windows системах также, как и в UNIX-подобных существует один корневой каталог со вложенными директориями, имеющими названия «c:», «d:» и т. д. В эти каталоги монтируются разделы жёсткого диска. То есть, c:\ - это всего лишь ссылка на file:///c:/. Однако, в отличие от UNIX-подобных файловых систем, в Windows запись в корневой каталог запрещена, как и просмотр его содержимого.

В UNIX существует только один корневой каталог, а все остальные файлы и каталоги вложены в него. Чтобы получить доступ к файлам и каталогам на каком-нибудь диске, необходимо примонтировать этот диск командой mount. Например, чтобы открыть файлы на CD, нужно, говоря простым языком, сказать операционной системе: «возьми файловую систему на этом компакт-диске и покажи её в каталоге /mnt/cdrom». Все файлы и каталоги, находящиеся на CD, появятся в этом каталоге /mnt/cdrom, который называется точкой монтирования (англ. mount point). В большинстве UNIX-подобных систем съёмные диски (дискеты и CD), флеш-накопители и другие внешние устройства хранения данных монтируют в каталог /mnt,/mount или /media. Unix и UNIX-подобные операционные системы также позволяет автоматически монтировать диски при загрузке операционной системы.

Обратите внимание на использование слешей в файловых системах Windows, UNIX и UNIX-подобных операционных системах (В Windows используется обратный слеш «\», а в UNIX и UNIX-подобных операционных системах простой слеш «/»)

Кроме того, следует отметить, что вышеописанная система позволяет монтировать не только файловые системы физических устройств, но и отдельные каталоги (параметр --bind) или, например, образ ISO (опция loop). Такие надстройки, как FUSE, позволяют также монтировать, например, целый каталог на FTP и ещё очень большое количество различных ресурсов.

Ещё более сложная структура применяется в NTFS и HFS. В этих файловых системах каждый файл представляет собой набор атрибутов. Атрибутами считаются не только традиционные только для чтения, системный, но и имя файла, размер и даже содержимое. Таким образом, для NTFS и HFS то, что хранится в файле, - это всего лишь один из его атрибутов.

Если следовать этой логике, один файл может содержать несколько вариантов содержимого. Таким образом, в одном файле можно хранить несколько версий одного документа, а также дополнительные данные (значок файла, связанная с файлом программа). Такая организация типична для HFS на Macintosh.


32. Функциональные компоненты ОС. Управление процессами.

Управление процессами:

Важнейшей частью операционной системы, непосредственно влияющей на функционирование вычислительной машины, является подсистема управления процессами. Процесс (или по-другому, задача) - абстракция, описывающая выполняющуюся программу. Для операционной системы процесс представляет собой единицу работы, заявку на потребление системных ресурсов.

В многозадачной (многопроцессной) системе процесс может находиться в одном из трех основных состояний:

ВЫПОЛНЕНИЕ - активное состояние процесса, во время которого процесс обладает всеми необходимыми ресурсами и непосредственно выполняется процессором;

ОЖИДАНИЕ - пассивное состояние процесса, процесс заблокирован, он не может выполняться по своим внутренним причинам, он ждет осуществления некоторого события, например, завершения операции ввода-вывода, получения сообщения от другого процесса, освобождения какого-либо необходимого ему ресурса;

ГОТОВНОСТЬ - также пассивное состояние процесса, но в этом случае процесс заблокирован в связи с внешними по отношению к нему обстоятельствами: процесс имеет все требуемые для него ресурсы, он готов выполняться, однако процессор занят выполнением другого процесса.

В ходе жизненного цикла каждый процесс переходит из одного состояния в другое в соответствии с алгоритмом планирования процессов, реализуемым в данной операционной системе.

Стандарт CP/M

Начало созданию операционных систем для микроЭВМ положила ОС СР/М. Она была разработана в 1974 году, после чего была установлена на многих 8-разрядных машинах. В рамках этой операционной системы было создано программное обеспечение значительного объема, включающее трансляторы с языков Бейсик, Паскаль, Си, Фортран, Кобол, Лисп, Ада и многих других, текстовые. Они позволяют подготавливать документы гораздо быстрее и удобнее, чем с помощью пишущей машинки.

Стандарт MSX

Этот стандарт определял не только ОС, но и характеристики аппаратных средств для школьных ПЭВМ. Согласно стандарту MSX машина должна была иметь оперативную память объемом не менее 16 К, постоянную память объемом 32 К с встроенным интерпретатором языка Бейсик, цветной графический дисплей с разрешающей способностью 256х192 точек и 16 цветами, трехканальный звуковой генератор на 8 октав, параллельный порт для подключения принтера и контроллер для управления внешним накопителем, подключаемым снаружи.

Операционная система такой машины должна была обладать следующими свойствами: требуемая память - не более 16 К, совместимость с СР/М на уровне системных вызовов, совместимость с DOS по форматам файлов на внешних накопителях на основе гибких магнитных дисков, поддержка трансляторов языков Бейсик, Си, Фортран и Лисп.

Пи - система

В начальный период развития персональных компьютеров была создана операционная система USCD p-system. Основу этой системы составляла так называемая П-машина - программа, эмулирующая гипотетическую универсальную вычислительную машину. П-машина имитирует работу процессора, памяти и внешних устройств, выполняя специальные команды, называемые П-кодом. Программные компоненты Пи-системы (в том числе компиляторы) составлены на П-коде, прикладные программы также компилируются в П-код. Таким образом, главной отличительной чертой системы являлась минимальная зависимость от особенностей аппаратуры ПЭВМ. Именно это обеспечило переносимость Пи-системы на различные типы машин. Компактность П-кода и удобно реализованный механизм подкачки позволял выполнять сравнительно большие программы на ПЭВМ, имеющих небольшую оперативную память.

Управление вводом/выводом.

Устройства ввода-вывода делятся на два типа: блок-ориентированные устройства и байт-ориентированные устройства. Блок-ориентированные устройства хранят информацию в блоках фиксированного размера, каждый из которых имеет свой собственный адрес. Самое распространенное блок-ориентированное устройство - диск. Байт-ориентированные устройства не адресуемы и не позволяют производить операцию поиска, они генерируют или потребляют последовательность байтов. Примерами являются терминалы, строчные принтеры, сетевые адаптеры. Электронный компонент называется контроллером устройства или адаптером. Операционная система имеет дело с контроллером. Контроллер выполняет простые функции, осуществляет контроль и исправляет ошибки. Каждый контроллер имеет несколько регистров, которые используются для взаимодействия с центральным процессором. ОС выполняет ввод-вывод, записывая команды в регистры контроллера. Контроллер гибкого диска IBM PC принимает 15 команд, таких как READ, WRITE, SEEK, FORMAT и т.д. Когда команда принята, процессор оставляет контроллер и занимается другой работой. При завершении команды контроллер организует прерывание для того, чтобы передать управление процессором операционной системе, которая должна проверить результаты операции. Процессор получает результаты и статус устройства, читая информацию из регистров контроллера.

Основная идея организации программного обеспечения ввода-вывода состоит в разбиении его на несколько уровней, причем нижние уровни обеспечивают экранирование особенностей аппаратуры от верхних, а те, обеспечивают удобный интерфейс для пользователей.

Ключевым принципом является независимость от устройств . Вид программы не должен зависеть от того, читает ли она данные с гибкого диска или с жесткого диска. Другим важным вопросом для программного обеспечения ввода-вывода является обработка ошибок. Вообще говоря, ошибки следует обрабатывать как можно ближе к аппаратуре. Если контроллер обнаруживает ошибку чтения, то он должен попытаться ее скорректировать. Если же это ему не удается, то исправлением ошибок должен заняться драйвер устройства. И только если нижний уровень не может справиться с ошибкой, он сообщает об ошибке верхнему уровню.

Еще один ключевой вопрос - это использование блокирующих (синхронных) и неблокирующих (асинхронных) передач. Большинство операций физического ввода-вывода выполняется асинхронно - процессор начинает передачу и переходит на другую работу, пока не наступает прерывание. Необходимо, чтобы операции ввода-вывода были блокирующие - после команды READ программа автоматически приостанавливается до тех пор, пока данные не попадут в буфер программы.

Последняя проблема состоит в том, что одни устройства являются разделяемыми(диски: одновременный доступ нескольких пользователей к диску не представляет собой проблему), а другие - выделенными(принтеры: нельзя смешивать строчки, печатаемые различными пользователями).

Для решения поставленных проблем целесообразно разделить программное обеспечение ввода-вывода на четыре слоя (рисунок 2.30):

· Обработка прерываний,

· Драйверы устройств,

· Независимый от устройств слой операционной системы,

· Пользовательский слой программного обеспечения.

Понятие аппаратного прерывания и его обработка.

Асинхронные или внешние (аппаратные) прерывания - события, которые исходят от внешних источников (например, периферийных устройств) и могут произойти в любой произвольный момент: сигнал от таймера, сетевой карты или дискового накопителя, нажатие клавиш клавиатуры, движение мыши; Они требуют моментальной реакции (обработки).

Практически все системы ввода/вывода в компьютере работают с использованием прерываний. В частности, когда вы нажимаете клавиши или щелкаете мышью, аппаратура вырабатывает прерывания. В ответ на них система, соответственно, считывает код нажатой клавиши или запоминает координаты курсора мыши. Прерывания вырабатываются контроллером диска, адаптером локальной сети, портами последовательной передачи данных, звуковым адаптером и другими устройствами.

Асинхронный ввод/вывод сиспользованием нескольких потоков

Перекрывающийся и расширенный ввод/вывод позволяют добиться асинхронного выполнения операций ввода/вывода в пределах единственного потока, хотя для поддержки этой функциональности ОС создает собственные потоки. В том или ином виде методы этого типа часто используются во многих ранних ОС для поддержки ограниченных форм выполнения асинхронных операций в однопоточных системах.

Однако Windows обеспечивает многопоточную поддержку, поэтому становится возможным достижение того же эффекта за счет выполнения синхронных операций ввода/вывода в нескольких, выполняемых независимо потоках. Ранее эти возможности уже были продемонстрированы на примере многопоточных серверов и программы grepMT (глава 7). Кроме того, потоки обеспечивают концептуально последовательный и, предположительно, гораздо более простой способ выполнения асинхронных операций ввода/вывода. В качестве альтернативы методам, используемым в программах 14.1 и 14.2, можно было бы предоставить каждому потоку собственный дескриптор файла, и тогда каждый из потоков мог бы обрабатывать в синхронном режиме каждую четвертую запись.

Такой способ использования потоков продемонстрирован в программе atouMT, которая в книге не приводится, но включена в материал, размещенный на Web-сайте. Программа atouMT не только способна выполняться под управлением любой версии Windows, но и более проста по сравнению с любым из двух вариантов программ асинхронного ввода/вывода, поскольку учет использования ресурсов в этом случае менее сложен. Каждый поток просто поддерживает собственные буферы в собственном стеке и выполняет в цикле последовательность синхронных операций чтения, преобразования и записи. При этом производительность программы остается на достаточно высоком уровне.

Примечание

В программе atouMT.с, которая находится на Web-сайте, содержатся комментарии по поводу нескольких возможных "ловушек", которые могут поджидать вас при организации доступа одновременно нескольких потоков к одному и тому же файлу. В частности, все отдельные дескрипторы файлов должны создаваться с помощью функции CreateHandle, а не функции DuplicateHandle.

Лично я предпочитаю использовать многопоточную обработку файлов, а не асинхронные операции ввода/вывода. Потоки легче программировать, и в большинстве случаев они обеспечивают более высокую производительность.

Существуют два исключения из этого общего правила. Первое из них, как было показано ранее в этой главе, касается ситуаций, в которых может быть только одна невыполненная операция, и в целях синхронизации можно использовать дескриптор файла. Второе, более важное исключение встречается в случае портов завершения асинхронного ввода/вывода, о чем будет говориться в конце настоящей главы.

Из книги Давайте создадим компилятор! автора Креншоу Джек

Из книги Программирование на языке Пролог автора Клоксин У.

Из книги Язык программирования С# 2005 и платформа.NET 2.0. автора Троелсен Эндрю

Из книги Руководство администратора баз данных Informix. автора Кустов Виктор

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

2.2.3.2 Асинхронный ввод-вывод Для ускорения операций ввода-вывода сервер использует собственный пакет асинхронного ввода-вывода (AIO) или пакет асинхронного ввода-вывода ядра ОС (KAIO), если он доступен. Пользовательские запросы на ввод-вывод обрабатываются асинхронно,

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Ввод/вывод Как вы знаете, операторы << и >> выполняют сдвиг числового значения влево и вправо на опеределенное число бит. В программах, приведенных в нашей книге, эти операторы также используются для ввода информации с клавиатуры и вывода на экран.Если с левой стороны

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Ввод и вывод Два класса библиотеки KERNEL обеспечивают основные средства ввода и вывода: FILE и STD_FILES.Среди операций, определенных для объекта f типа FILE, есть следующие:create f.make ("name") -- Связывает f с файлом по имени name.f.open_write -- Открытие f для записиf.open_read -- Открытие f для

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

ГЛАВА 14 Асинхронный ввод/вывод и порты завершения Операциям ввода и вывода присуща более медленная скорость выполнения по сравнению с другими видами обработки. Причиной такого замедления являются следующие факторы: Задержки, обусловленные затратами времени на поиск

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

10.1.7. Простой ввод/вывод Вы уже знакомы с некоторыми методами ввода/вывода из модуля Kernel; мы вызывали их без указания вызывающего объекта. К ним относятся функции gets и puts, а также print, printf и p (последний вызывает метод объекта inspect, чтобы распечатать его в понятном для нас

Из книги Язык программирования Си для персонального компьютера автора Бочков C. О.

Из книги Linux программирование в примерах автора Роббинс Арнольд

Глава 6 Ввод и вывод В этой главе мы рассмотрим некоторые встроенные средства для записи данных в файл и считывания их из файла. Такие средства можно также применять и для форматирования объектов данных программы, чтобы получить желаемую форму их внешнего представления.

Из книги Основы программирования на Java автора Сухов С. А.

Ввод и вывод Функции ввода и вывода в стандартной библиотеке Си позволяют читать данные из файлов или получать их с устройств ввода (например, с клавиатуры) и записывать данные в файлы, или выводить их на различные устройства (например, на принтер).Функции ввода/вывода

Из книги QT 4: программирование GUI на С++ автора Бланшет Жасмин

4.4. Ввод и вывод Все операции Linux по вводу/выводу осуществляются посредством дескрипторов файлов. Данный раздел знакомит с дескрипторами файлов, описывает, как их получать и освобождать, и объясняет, как выполнять с их помощью

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

Из книги автора

Глава 12. Ввод-вывод Почти в каждом приложении приходится читать или записывать файлы или выполнять другие операции ввода-вывода. Qt обеспечивает великолепную поддержку ввода-вывода при помощи QIODevice - мощной абстракции «устройств», способных читать и записывать

Из книги автора

Ввод и вывод Также мне кажется очень важным, чтобы мои результаты подпитывались соответствующим «вводом». Написание программного кода – творческая работа. Обычно мои творческие способности в наибольшей степени проявляются тогда, когда я сталкиваюсь с творческим

Программист, разрабатывающий прикладные программы, не должен думать о таких вещах, как способ работы системных программ с регистрами устройств. Система скрывает от приложений детали низкоуровневой работы с устройствами. Однако различие между организацией ввода/вывода по опросу и по прерываниям находит определенное отражение и на уровне системных функций, в виде функций для синхронного и асинхронного ввода/вывода.

Выполнение функции синхронного ввода/вывода включает в себя запуск операции ввода/вывода и ожидание завершения этой операции. Только после завершения ввода/вывода функция возвращает управление вызвавшей программе.

Синхронный ввод/вывод – это наиболее привычный для программистов способ работы с устройствами. Стандартные процедуры ввода/вывода языков программирования работают именно таким способом.

Вызов функции асинхронного ввода/вывода означает только запуск соответствующей операции. После этого функция сразу возвращает управление вызвавшей программе, не дожидаясь завершения операции.

Рассмотрим, например, асинхронный ввод данных. Понятно, что программа не может обращаться к данным, пока нет уверенности, что их ввод завершен. Но вполне возможно, что программа может пока что заняться другой работой, а не простаивать в ожидании.

Рано или поздно программа все-таки должна приступить к работе с введенными данными, но предварительно убедиться, что асинхронная операция уже завершилась. Для этого различные ОС предоставляют средства, которые можно разбить на три группы.

· Ожидание завершения операции. Это как бы «вторая половина синхронной операции». Программа сначала запустила операцию, потом выполнила какие-то посторонние действия, а теперь ждет окончания операции, как при синхронном вводе/выводе.

· Проверка завершения операции. При этом программа не ожидает, а только проверяет состояние асинхронной операции. Если ввод/вывод еще не завершен, то программа имеет возможность еще какое-то время погулять.

· Назначение процедуры завершения. В этом случае, запуская асинхронную операцию, программа пользователя указывает системе адрес пользовательской процедуры или функции, которая должна быть вызвана системой после завершения операции. Сама программа может больше не интересоваться ходом ввода/вывода, система напомнит ей об этом в нужный момент, вызвав указанную функцию. Этот способ наиболее гибкий, поскольку в процедуре завершения пользователь может предусмотреть любые действия.

В Windows прикладной программе доступны все три способа завершения асинхронных операций. В UNIX асинхронных функций ввода/вывода нет, однако тот же эффект асинхронности может быть достигнут иначе, путем запуска дополнительного процесса.

Асинхронное выполнение ввода/вывода позволяет в некоторых случаях повысить производительность работы и обеспечить дополнительные функциональные возможности. Без такой простейшей формы асинхронного ввода, как «ввод с клавиатуры без ожидания», были бы невозможны многочисленные компьютерные игры и тренажеры. В то же время логика программы, использующей асинхронные операции, сложнее, чем при синхронных операциях.

А в чем заключается упомянутая выше связь между синхронными/асинхронными операциями и способами организации ввода/вывода, рассмотренными в предыдущем пункте? Ответьте сами на этот вопрос.

В компьютерных системах под синхронным вводом и синхронным выводом понимают процессы ввода-вывода отсчётов данных, при которых явно сохраняются интервалы времени (периодичность) передачи отсчётов на ввод или на вывод. Синхронность ввода-вывода обеспечивается с помощью той или иной аппаратной поддержки (таймеры и различные другие периферийные устройства со средствами синхронизации и с применением буферизации данных для выравнивания потока ввода-вывода данных). При этом, термин синхронный ввод-вывод не означает обязательного наличия сигнала синхронизации у интерфейса ввода-вывода, и синхронность может обеспечиваться как внутренней, так и внешней синхронизацией.

Обычно в процессорных и измерительных системах направление потока данных (на ввод или на вывод) считают относительно компьютера (процессора), стоящего в центре рассматриваемой архитектуры. В частности, отсчёты АЦП и цифровых (дискретных) входов считают данными на ввод, а отсчёты ЦАП и цифровых (управляющих) выходов – данными на вывод.

При асинхронным вводе и выводе не сохраняются интервалы времени (периодичность) передачи отсчётов на ввод или на вывод. При этом, данные поступают на ввод или вывод в темпе самого интерфейса передачи данных, с непредсказуемыми задержками буферизации, без сохранения каких-либо временны̀х интервалов. В частности, это означает для программиста, что при использовании асинхронных функций ввода-вывода бессмысленно сопоставлять моменты вызова функции асинхронного ввода-вывода с физическими моментами выполнения данной операции “по ту сторону интерфейса” (подобное сопоставление имеет смысл только лишь при статистическом методе обработки данных). Факт выполнения асинхронной операции на вывод может быть проверен с помощью подтверждения (если данная операция на вывод имеет подтверждение, или подтверждение можно получить последующей операцией ввода данных). При асинхронном вводе-выводе упомянутая выше буферизация данных может сыграть противоположную роль и увеличить неопределённость времени доставки данных при отсутствии механизма синхронизации и управления трафиком передачи данных.

Модуль АЦП/ЦАП
16/32 каналов, 16 бит, 2 МГц, USB, Ethernet