Скачиваний:
2
Добавлен:
03.01.2024
Размер:
3.49 Mб
Скачать

3.Низкокоуровневый интерфейс языка Си. Файловые дескрипторы fd (описатели)

В языке при осуществлении ввода-вывода мы используем указатель FILE*.

Даже функция printf() в итоге сводится к вызову

 

Интерфейсы для файлового

 

 

Файл − это

 

 

 

 

vfprintf(stdout,...), разновидности функции fprintf(); константа

 

ввода-вывода

 

 

логический

 

 

 

 

stdout имеет тип struct _IO_FILE*, синонимом которого

 

в ОС Linux

 

 

 

набор данных

 

 

 

 

является тип FILE*.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Т.е., консольный ввод-вывод − это файловый ввод-вывод.

 

 

 

 

 

 

 

 

 

 

Стандартный поток ввода, стандартный поток вывода и

 

 

 

 

 

 

 

 

 

 

1.Интерфейс системных вызовов

 

 

 

 

 

 

 

 

 

поток ошибок (как в C, так и в C++) − это файлы.

 

 

 

 

 

 

 

 

В Linux все, куда можно что-то записать или откуда можно

предлагающий системные

 

2.Стандартная библиотека

 

 

 

 

функции низкого уровня,

 

ввода-вывода, предлагающая

 

 

 

 

что-то прочитать представлено (или может быть

 

 

 

 

 

непосредственно

 

функции буферизованного

 

 

 

 

представлено) в виде файла.

 

 

 

 

 

 

 

взаимодействующие с ядром

 

ввода-вывода.

 

 

 

 

Экран, клавиатура, аппаратные и виртуальные

 

операционной системы

 

 

 

 

 

 

 

 

 

устройства, каналы, сокеты − все это файлы.

 

 

 

 

 

 

 

 

 

 

 

 

Файловый дескриптор (fd file descriptor) − это целое число

Это очень удобно, поскольку ко всему можно применять одни

 

и те же механизмы ввода-вывода, с которыми мы и

(int), соответствующее открытому файлу.

 

 

 

 

познакомимся в этой главе.

Дескриптор, соответствующий реально открытому файлу

 

 

 

Владение механизмами низкоуровневого ввода-вывода дает

всегда больше или равен нулю.

 

 

 

 

 

 

 

 

свободу перемещения данных в Linux.

Копия таблицы дескрипторов (читай: таблицы открытых

 

 

 

Работа с локальными файловыми системами, межсетевое

файлов внутри процесса) скрыта в ядре ОС.

 

 

 

 

 

Мы не можем получить прямой доступ к этой таблице, как при

 

взаимодействие, работа с аппаратными устройствами,−

 

работе с окружением через environ.

 

 

 

 

 

все это осуществляется в Linux посредством низкоуровневого

 

 

 

 

 

Можно, конечно, кое-что "вытянуть" через дерево /proc, но

 

 

 

 

ввода-вывода.

 

 

 

 

нам это не надо.

 

 

 

 

 

 

 

При запуске программы в системе создается новый процесс

 

 

 

 

 

 

 

 

Программист должен лишь понимать, что каждый процесс

 

 

 

 

(здесь есть свои особенности). У каждого процесса (кроме

 

 

 

 

имеет свою копию таблицы дескрипторов.

 

 

 

 

 

init) есть свой родительский процесс (parent process или

 

 

 

 

 

В пределах одного процесса все дескрипторы уникальны

 

 

 

 

просто parent), для которого новоиспеченный процесс

 

 

 

 

(даже если они соответствуют одному и тому же файлу или

 

 

 

 

является дочерним (child process, child). Каждый процесс

 

 

 

 

устройству).

 

 

 

 

 

 

 

 

получает копию окружения (environment) родительского

 

 

 

 

 

 

 

 

В разных процессах дескрипторы могут совпадать или не

 

 

 

 

процесса. Оказывается, кроме окружения дочерний процесс

 

 

 

 

совпадать − это не имеет никакого значения, поскольку у каждого

 

получает в качестве багажа еще и копию таблицы файловых

 

процесса свой собственный набор открытых файлов.

11

 

дескрипторов.

 

 

 

 

 

 

 

 

 

 

 

fd Файловые дескрипторы (описатели)

Сколько файлов может открыть процесс?

Вкаждой ОС есть свой лимит, зависящий от конфигурации ОС.

Вbash можно воспользоваться внутренней командой оболочки ulimit, чтобы узнать это значение:

$ ulimit –n # Сколько файлов может открыть процесс?

1024

$

Вкомандной оболочке (bash), открыты три файла:

стандартный ввод (дескриптор 0);

стандартный вывод (дескриптор 1);

стандартный поток ошибок (дескриптор 2).

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

Таким образом программа может осуществлять консольный ввод-вывод через эти дескрипторы.

Таблица дескрипторов, помимо всего прочего, содержит

информацию о текущей позиции чтения-записи для каждого дескриптора.

При открытии файла, позиция чтения-записи устанавливается

вноль.

Каждый прочитанный или записанный байт увеличивает на единицу указатель текущей позиции.

Открытие файла

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

Открытие файла является процедурой создания дескриптора или управляющего блока файла.

fd дескриптор файла хранит всю информацию о файле.

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

Например, на языке операция открытия файла возвращает дескриптор fd, который может быть задействован при выполнении операций чтения или записи.

Закрытие файла

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

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

Чтение данных из файла. Обычно это делается с текущей позиции. Пользователь должен задать объем считываемых данных и предоставить для них буфер в оперативной памяти.

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

12

fd Файловые дескрипторы (описатели)

Есть и ДРУГИЕ ОПЕРАЦИИ, например переименование файла, получение атрибутов файла и т. д.

Существует два способа выполнить последовательность действий над файлами:

1)В первом случае для каждой операции выполняются как универсальные, так и уникальные действия (схема stateless). Например, последовательность операций может быть такой: open, read1, close, ... open, read2, close, ... open, read3, close.

2)Альтернативный способ − это когда универсальные действия выполняются в начале и в конце последовательности операций, а для каждой промежуточной операции выполняются только уникальные действия.

Вэтом случае последовательность вышеприведенных операций будет выглядеть так: open, read1, ... read2, ... read3, close.

Вбольшинстве ОС используется второй способ, более экономичный и быстрый.

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

Средства низкоуровневого ввода-вывода языка Си

Предварительные описания функций ввода/вывода низкого уровня помещены в файл io.h. Кроме этого, файлы fcntl.h, sys\types.h и sys\stat.h содержат определения символических констант, используемых отдельными функциями

Для нормальной работы программы все эти файлы необходимо включить в ее исходный текст при помощи директивы препроцессора #include

Функции ввода-вывода низкого уровня осуществляют обмен с файлами или периферийными устройствами путем прямого обращения к соответствующим функциям операционной системы (системным вызовам)

Они не предоставляют возможности буферизации

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

Команды:

open - открыть файл close - закрыть файл create - создать файл

eof - проверка на конец файла

lseek - переместить указатель файла в заданное положение read - читать данные из файла

write - записать данные в файл

tell - получить текущее положение указателя файла

Подробное описание низкоуровневого ввода-вывода − см. справочник по языку Си.

Описание файловых дескрипторов будет подробно рассмотрено на курсе по ОС (раздел «файловые системы»).

Файловый

Поток (указатель)

Описание

дескриптор

 

 

 

 

 

0

stdin

Стандартный ввод

1

 

 

stdout

Стандартный вывод

2

 

 

stderr

Сообщения об ошибках

 

 

 

13

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

 

 

 

 

 

 

file1

file2

Файловая система

14

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

fd1

buf

fd2

file1

file2

Файловая система

15

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

 

fd1

->file1

 

buf

 

 

fd2

 

file1

file2

Файловая система

16

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

 

fd1

->file1

 

buf

 

 

fd2

 

file1

file2

Файловая система

17

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

 

fd1

->file1

 

buf

 

 

fd2

->file2

file1

file2

Файловая система

18

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

 

fd1

->file1

 

buf

 

 

fd2

->file2

file1

file2

Файловая система

19

Пример использования низкоуровневого ввода-вывода

Код программы

Память

Память

 

программы

ОС

fd1

buf

fd2 ->file2

file1

file2

Файловая система

© Кафедра вычислительных систем ГОУ ВПО «СибГУТИ»

20

Соседние файлы в папке Лекции