чинаются с косой черты (/). Например:
qnx/fsys | локальное имя |
company/xyz | локальное имя |
/company/xyz | глобальное имя |
Мы рекомендуем вам использовать название вашей компании в качестве префикса для всех регистрируемых имен, чтобы избежать конфликтов имен между программами разных производителей. |
Чтобы сделать возможным использование глобальных имен, хотя бы на одном узле сети должен быть запущен процесс, известный как определитель имен (утилита nameloc). Этот процесс ведет учет всех зарегистрированных глобальных имен.
В каждый момент времени в сети могут быть запущены до десяти определителей имен. Каждый хранит идентичные копии всех активных глобальных имен. Такая избыточность гарантирует нормальное функционирование сети, даже если один или несколько узлов, обеспечивающих определение имен, выйдут из строя одновременно.
Чтобы зарегистрировать имя, процесс сервер использует функцию Си qnx_name_attach(). Чтобы определить процесс по имени, процесс клиент использует функцию Си qnx_name_locate().
В QNX исчисление времени основывается на системном таймере, поддерживаемом операционной системой. Таймер содержит текущее значение Координированного Всемирного Времени (UTC) относительно 0 часов, 0 минут, 0 секунд, 1 января 1970 года. Чтобы определить местное время, функции исчисления времени используют переменную окружения TZ (которая описывается в книге Руководство пользователя).
Простые средства отсчета времени
Командные файлы и процессы могут делать паузу на определенное количество секунд, используя простые средства отсчета времени. В командных файлах для этой цели используется утилита sleep; в процессах используется функция Си sleep(). Также может использоваться функция delay(), которой в качестве аргумента передается длина интервала времени в миллисекундах.
Более сложное средство отсчета времени
Кроме того, процесс может создавать таймеры, устанавливать их на определенный интервал времени и удалять таймер. Эти средства отсчета времени основываются на спецификации POSIX Std 1003.4/Draft 9.
Процесс может создать один или больше таймеров. Эти таймеры могут быть любых типов и в любом сочетании. С учетом конфигурируемого ограничения общего числа таймеров, поддерживаемых операционной системой (смотри Proc в Описание утилит). Для создания таймера используйте функцию timer_create().
При установке таймеров вы можете использовать один из двух типов интервалов времени:
Вы также можете создать таймер, периодически срабатывающий с заданным интервалом времени. Например, вы установили таймер таким образом, чтобы он сработал завтра в 9 часов утра. Вы можете задать, чтобы после этого он срабатывал каждые 5 минут.
Вы также можете установить временной интервал для существующего таймера. Результат будет зависеть от типа интервала времени:
Чтобы установить таймер: | Используйте функцию: |
---|---|
Абсолютный или относительный интервал | timer_settime() |
Чтобы удалить таймер, используйте функцию Си timer_delete().
Вы можете установить разрешение для таймера с помощью утилиты ticksize или функции qnx_timerperiod(). Вы можете настраивать разрешение от 500 микросекунд до 50 миллисекунд.
Чтобы узнать оставшийся от таймера интервал или проверить, не был ли таймер удален, используйте функцию Си timer_gettime().
Обработчики прерываний обслуживают систему аппаратных прерываний компьютера - они реагируют на аппаратные прерывания и осуществляют передачу данных между компьютером и внешними устройствами на низком уровне.
Обработчики прерываний физически являются частью стандартного процесса QNX (например, драйвер), но они всегда выполняются асинхронно по отношению к процессу, в который они включены.
Обработчик прерываний:
Несколько процессов могут обрабатывать одно и то же прерывание (если это поддерживается аппаратно). Когда происходит физическое прерывание, все обработчики прерываний будут по очереди получать управление. Не должно делаться никаких предположений относительно порядка, в котором будут вызываться обработчики прерываний, разделяющие одно и то же прерывание.
Если вы хотите: | Используйте функцию: |
---|---|
Установить обработчик прерывания | qnx_hint_attach() |
Удалить обработчик прерывания | qnx_hint_detach() |
Обработчики прерывания таймера
Вы можете установить обработчик прерывания непосредственно для системного таймера таким образом, что обработчик будет вызываться по каждому прерыванию таймера. Чтобы установить период, вы можете использовать утилиту ticksize.
Вы можете также установить обработчик прерывания для отмасштабированного прерывания таймера, которое будет происходить каждые 50 миллисекунд, независимо от tick size. Эти таймеры предлагают низкоуровневую альтернативу POSIX 1003.4 таймерам.
Эта глава охватывает следующие темы:
Пространство имен ввода/вывода
Ресурсы ввода/вывода (I/O, от английского Input/Output) в QNX не встроены внутрь Микроядра. Процессы обслуживающие ввод/вывод запускаются динамически во время работы системы. Так как файловая система QNX является необязательным элементом, то пространство путей (полных имен файлов и каталогов) не встроено внутрь файловой системы, в отличие от большинства монолитных систем.
В QNX пространство имен путей разделено на области полномочий. Любой процесс, выполняющий файл-ориентированное обслуживание ввода/вывода, должен зарегистрировать у Менеджера процессов свой префикс, определяя часть пространства имен, которое он хочет контролировать (т.е. область своих полномочий). Эти префиксы составляют дерево префиксов, которое хранится в памяти на каждом компьютере под управлением QNX.
Префиксы менеджера ввода/вывода
Когда процесс открывает файл, то полное имя файла сопоставляется с деревом префиксов с тем, чтобы отправить запрос open() к соответствующему менеджеру ресурсов ввода/вывода. Например, Менеджер устройств (Dev) обычно регистрирует префикс /dev. Если процесс вызывает open() с аргументом /dev/xxx, то совпадет префикс /dev и open() будет направлен к Dev (его владельцу).
Дерево префиксов может содержать частично перекрывающиеся области полномочий. В этом случае ищется наиболее длинное совпадение. Например, предположим, что есть три зарегистрированных префикса:
/ | дисковая файловая система (Fsys) |
/dev | система символьных устройств (Dev) |
/dev/hd0 | дисковый том без разделов (Fsys) |
Менеджер файловой системы зарегистрировал два префикса, один для смонтированной файловой системы QNX (т.е. /) и один для блок-ориентированного файла, который представляет весь физический жесткий диск (т.е. /dev/hd0). Менеджер устройств зарегистрировал единственный префикс. Следующая таблица иллюстрирует правило наиболее длинного совпадения при разборе имен путей.
Имя пути: | Совпадает: | Относится к: |
---|---|---|
/dev/con1 | /dev | Dev |
/dev/hd0 | /dev/hd0 | Fsys |
/usr/dtdodge/test | / | Fsys |
Дерево префиксов хранится как список префиксов, разделенных двоеточиями, следующим образом:
prefix=pid,unit:prefix=pid,unit:prefix=pid,unit
где pid - это ID процесса менеджера ресурсов I/O, а unit - это один символ, используемый менеджером для нумерации префиксов, которыми он владеет. В приведенном выше примере, если Fsys был бы процессом 3 и Dev был бы процессом 5, то дерево префиксов выглядело бы как:
/dev/hd0=3,a:/dev=5,a:/=3,e
Если вы хотите: | Используйте: |
---|---|
Показать дерево префиксов | Утилиту prefix |
Получить дерево префиксов внутри программы на языке Си | Функцию qnx_prefix_query() |
QNX поддерживают концепцию сетевого корня, которая позволяет сопоставлять имя пути с деревом префиксов на конкретном узле. Для обозначения узла имя пути начинается с двух косых черт, за которыми следует номер узла. Это также позволяет вам легко получать доступ к файлу и устройству, которые лежат за пределами пространства путей вашего узла. Например, в типичной сети QNX возможны следующие имена путей:
/dev/ser1 | локальный последовательный порт |
//10/dev/ser1 | последовательный порт в узле 10 |
//0/dev/ser1 | локальный последовательный порт |
//20/usr/dtdodge/test | файл на узле 20 |
Заметьте, что //0 всегда указывает на локальный узел
Когда программа выполняется на удаленном узле, вы обычно хотите, чтобы она рассматривала имена путей в контексте пространства имен своего узла. Например, эта команда:
//5 ls /
которая запускает утилиту ls на узле 5, возвратит то же самое, что и:
ls /
запускаемая на своем узле. В обоих случаях "/" будет соотноситься с деревом префиксов на вашем узле, а не на узле 5. В противном случае, можно представить себе беспорядок, который мог бы возникнуть, если бы префикс "/" рассматривался своим как для узла 5, так и для своего узла: выбирались бы одновременно файлы из разных файловых систем!
Чтобы правильно интерпретировать имена путей, каждый процесс имеет сетевой корень по умолчанию, который определяет, дерево префиксов какого узла будет использоваться для разбора любых имен путей, начинающихся с одиночной косой черты ("/"). Когда разбирается имя пути, начинающееся с одиночной косой черты, то оно предваряется сетевым корнем по умолчанию. Например, если процесс имеет сетевой корень по умолчанию //9, тогда:
/usr/home/luc
будет разбираться, как:
//9/usr/home/luc
что может быть интерпретировано, как "разобрать путь /usr/home/luc, используя дерево префиксов 9-го узла".
Сетевой корень по умолчанию наследуется процессами при их создании и соответствует локальному узлу, на котором запускается система. Например, допустим, что вы работаете на узле 9, находясь в командном интерпретаторе, для которого сетевой корень по умолчанию установлен как узел 9 (весьма типичный случай). Если вы выполните команду:
ls /
команда унаследует сетевой корень по умолчанию //9, и в результате вы получите:
ls //9/
Подобно тому, если бы вы ввели команду:
//5 ls /
Вы запустили команду ls на узле 5, но она по-прежнему унаследует сетевой корень по умолчанию //9, поэтому в результате вы опять получите ls //9/. В обоих случаях имя пути разбирается относительно одного и того же пространства имен.
Если вы хотите: | Используйте: |
---|---|
Получить текущий сетевой корень по умолчанию | Функцию qnx_prefix_getroot() |
Установить сетевой корень по умолчанию | Функцию qnx_prefix_setroot() |
Запустить программу с новым сетевым корнем по умолчанию | Утилиту on |
Если запущено одновременно несколько процессов, они не обязательно имеют один и тот же сетевой корень по умолчанию, даже если они выполняются на одном и том же узле. К примеру, один из процессов мог унаследовать сетевой корень по умолчанию от родительского процесса на каком-либо другом узле сети, либо его сетевой корень по умолчанию мог быть в явном виде задан родительским процессом.
При передаче имени пути между процессами, чьи сетевые корни могут отличаться (например, передавая файл спулеру для печати), вы должны добавить сетевой корень в начало имени пути, прежде чем передать путь другому процессу. Если вы уверены, что посылающий процесс и получатель имеют один и тот же сетевой корень по умолчанию (или имя пути уже начинается с //узел/), то вы можете опустить этот шаг.
Мы рассмотрели префиксы, которые регистрируются менеджерами ресурсов I/O. Вторая форма префикса известна как псевдоним префикса, это простая подстановка строки вместо искомого префикса. Псевдоним префикса имеет форму:
prefix=строка-заменитель
Например, вы работаете на машине, у которой нет локальной файловой системы (поэтому нет и процесса, который бы отвечал за "/"). Однако, файловая система имеется на другом узле (допустим, 10), и вы хотите ее использовать как "/". Вы можете сделать это с помощью следующего псевдонима префикса:
/=//10/
Это приведет к тому, что ведущая косая черта (/) будет заменяться на префикс //10/. Например, путь /usr/dtdodge/test будет заменен следующим:
//10/usr/dtdodge/test
Это новое имя пути будет снова сравниваться с деревом префиксов; на этот раз будет использоваться уже дерево префиксов 10 узла, т.к. имя пути начинается с //10. Это приведет к Менеджеру файловой системы на узле 10, которому и будет направлен запрос, например, open(). С помощью всего лишь нескольких символов этот псевдоним позволил нам обращаться к удаленной файловой системе как к локальной.
Для того чтобы выполнить перенаправление, не обязательно запускать локальную файловую систему. Дерево префиксов для бездисковой рабочей станции может выглядеть примерно так:
/dev=5,a:/=//10/
При таком дереве префиксов номера путей, начинающихся с /dev, будут направляться к локальному менеджеру символьных устройств, в то время как запросы с любыми другими именами путей, будут направляться к удаленной файловой системе.
Вы также можете использовать псевдонимы создания специальных имен устройств. Например, если спулер печати запущен на узле 20, то вы можете создать для него локальный псевдоним следующим образом:
/dev/printer=//20/dev/spool
Любой запрос на открытие локального принтера /dev/printer будет направляться по сети к реальному спулеру. Аналогичным образом, если не существует локального дисковода для гибких дисков, псевдоним для удаленного дисковода на узле 20 может иметь вид:
/dev/fd0=//20/dev/fd0
В обоих рассмотренных выше случаях можно не использовать перенаправление с помощью псевдонима, а обращаться непосредственно к удаленному ресурсу следующим образом:
//20/dev/spool ИЛИ //20/dev/fd0
Путь не обязательно должен начинаться с одной или двух косых черт. В таких случаях путь считается относительным по отношению к текущему рабочему каталогу. QNX хранит текущий рабочий каталог в виде строки символов. Относительные пути преобразуются в полные сетевые имена пути добавлением текущего рабочего каталога в начало относительного пути.
Учтите, что результат зависит от того, начинается ли текущий рабочий каталог с одинарной косой черты, либо с сетевого корня.
Если текущий рабочий каталог начинается с двойной косой черты (сетевого корня), он называется определенным и привязан к пространству имен указанного узла. В противном случае, если он начинается с одинарной косой черты, то в начало добавляется сетевой корень по умолчанию.
Например, эта команда:
cd //18/
является примером первой (определенной) формы и привязывает последующие разборы относительных путей к узлу 18, независимо от того, какое значение сетевого корня по умолчанию. Выполнив затем команду cd dev, вы попадете в //18/dev.
С другой стороны, такая команда:
cd /
является примером второй формы, когда сетевой корень по умолчанию влияет на разбор относительного пути. Например, если сетевой корень по умолчанию //9, тогда, выполнив команду cd dev, вы попадете в //9/dev. Так как текущий рабочий каталог не начинается с указания узла, то сетевой корень по умолчанию добавляется для получения полного сетевого пути.
Это на самом деле не так сложно, как может показаться. Обычно сетевые корни (//узел/) не указываются, и все, что вы делаете, просто работает внутри пространства имен вашего узла (определяемого вашим сетевым корнем по умолчанию). Большинство пользователей, войдя в систему, принимают нормальный сетевой корень по умолчанию (т.е. пространство имен их собственного узла) и работают внутри этой среды.
В некоторых традиционных UNIX системах команда cd (сменить директорию) модифицирует заданный путь, если он содержит символьные ссылки. Как результат, путь к новому текущему рабочему каталогу - который можно посмотреть командой pwd, может отличаться от того, который был задан в команде cd.
В QNX, однако, cd не изменяет путь - за исключением сокращенных ссылок "..". Например:
cd /usr/home/luc/test/../doc
установит текущий рабочий каталог /usr/home/luc/doc, даже если некоторые элементы этого пути являются символическими связями.
Более подробную информацию о символических связях можно получить в главе "Менеджер файловой системы".
Чтобы получить полное сетевое имя пути, используйте утилиту fullpath. |
При открытии ресурса I/O, open() возвращает целое число, называемое дескриптор файла (FD), которое используется затем, чтобы направлять все последующие запросы I/O к данному менеджеру. (Внутри библиотечных процедур для направления опроса используется вызов ядра Sendfd().)
Пространство дескрипторов файлов, в отличие от пространства имен пути, полностью локально для каждого процесса. Менеджер использует сочетание PID и FD, чтобы определить управляющую структуру, созданную предыдущим вызовом open(). Эта структура называется блок управления файлом (OCB от английского open control block) и хранится внутри менеджера I/O.
Следующая диаграмма показывает, как менеджер I/O находит соответствующий OCB для пары PID и FD.
PID и FD определяют OCB для Менеджера ввода/вывода.
OCB содержит действующую информацию об открытом ресурсе. Например, файловая система хранит здесь текущий указатель на позицию в файле. Каждый вызов open() создает новый OCB. Таким образом, если процесс дважды открывает один и тот же файл, любые вызовы lseek(), использующие один FD, не повлияют на текущую позицию для другого FD.
То же самое справедливо и для различных процессов, открывающих один и тот же файл.
Следующая диаграмма показывает два процесса, один из которых открывает файл дважды, а другой открывает этот же файл один раз. При этом нет разделяемых FD.
Процесс A открывает файл /tmp/file дважды. Процесс B открывает тот же файл один раз.
Несколько дескрипторов файла в одном или нескольких процессах могут указывать на один и тот же OCB. Это может быть достигнуто двумя способами:
Когда несколько FD указывают на один и тот же OCB, тогда любое изменение в состоянии OCB немедленно видимо для всех процессов, у которых есть дескрипторы файлов, указывающие на этот OCB.
Например, если один из процессов использует функцию lseek() для изменения текущей позиции, тогда чтение или запись начинается с новой позиции, независимо от того, какой из дескрипторов файла используется.
Следующая диаграмма показывает два процесса, из которых один открывает файл дважды, а затем вызывает dup(), чтобы получить третий дескриптор. Затем он создает дочерний процесс, который наследует все открытые файлы.
Процесс открывает файл дважды, а затем получает третий FD посредством dup(). Его дочерний процесс унаследует все эти три дескриптора файла.
Вы можете предотвратить наследование дескриптора файла при использовании spawn() или exec(), предварительно вызвав функцию fcntl() и установив флаг FD_CLOEXEC.
Эта глава охватывает следующие темы:
Менеджер файловой системы (Fsys) обеспечивает стандартизованные способы сохранения данных на дисках и доступа к ним. Fsys отвечает за обработку всех запросов на открытие, закрытие, чтение и запись файлов.
В QNX файл - это объект, в который может производиться запись, из которого может производиться чтение, либо и то и другое. QNX поддерживает шесть типов файлов; пять из них поддерживает Fsys:
Все эти типы файлов подробно описываются в этой главе. Шестой тип файлов - блок-ориентированные файлы - обслуживается Менеджером устройств.
Fsys поддерживает четыре различных метки времени для каждого файла. Это:
Доступ к регулярным файлам и каталогам управляется битами режима, хранящимися в inode (индексном дескрипторе) файла. Более подробно inode описан в секции "Связи и индексные дескрипторы (inodes)". Эти биты разрешают чтение, запись и выполнение в зависимости от эффективных ID пользователя и группы. При этом пользователи делятся на три категории:
Процесс может выполняться с ID пользователя или ID группы файла, а не родительского процесса. Механизм, который позволяет это, называется setuid (установить ID пользователя) и setgid (установить ID группы).
QNX рассматривает регулярный файл как последовательность байт с возможностью произвольного доступа и не имеющую другой предопределенной внутренней структуры. Прикладные программы сами несут ответственность за понимание структуры и содержания конкретного регулярного файла.
Регулярные файлы составляют большинство файлов в файловых системах. Файловые системы поддерживаются Менеджером файловой системы и реализованы на базе блок-ориентированных файлов, соответствующих разделам диска (разделы описаны в секции "Работа с дисками").
Каталог - это файл, который содержит элементы каталога. Каждый элемент каталога увязывает имя файла с файлом. Имя файла - это символьное имя, которое позволяет идентифицировать файл и работать с ним. Файл может быть идентифицирован несколькими именами (смотри секции "Связи и индексные дескрипторы (inodes)" и "Символические связи").
Следующая диаграмма показывает, как производится поиск файла с именем /usr/bill/file2.
Путь в структуре каталога QNX к файлу /usr/bill/file2.
Хотя каталог ведет себя во многом как стандартный файл, Менеджер файловой системы накладывает некоторые ограничения на операции, которые вы можете производить с каталогом. В частности, вы не можете открыть каталог для записи либо создать связь для каталога с помощью функции Си link().
Для чтения элементов каталога вы можете использовать набор функций Си, определенных POSIX, которые обеспечивают не зависимый от ОС доступ к элементам каталога. Эти функции включают:
Так как каталоги QNX - это просто файлы, содержащие "известную" информацию, вы можете также читать элементы каталога непосредственно функциями Си open() и read(). Однако эта техника не переносима - формат элементов каталога отличается в различных операционных системах.
В QNX регулярные файлы и файлы каталога хранятся как последовательность экстентов. Экстент - это непрерывная последовательность блоков на диске.
Файлы, которые состоят только из одного экстента, хранят информацию об экстенте в элементе каталога. Но, если файл состоит более чем из одного экстента, информация о расположении экстентов хранится в одном или более связных блоках экстентов (связные - имеющие прямые/обратные указатели). Каждый блок экстентов может содержать информацию не более чем о 60 экстентах.
Файл, состоящий из множества непрерывных областей на диске, называемых в QNX экстентами.
Когда Менеджеру файловой системы необходимо увеличить файл, он сначала пытается увеличить последний экстент, хотя бы даже на один блок. Но если последний экстент не может быть дополнен, то для расширения файла выделяется новый экстент.
Для выделения новых экстентов Менеджер файловой системы использует метод "первого попадания". Специальная таблица в Менеджере файловой системы содержит сведения обо всех блоках, описанных в файле /.bitmap (этот файл описан в секции "Ключевые компоненты раздела QNX"). Для каждого блока указывается размер соответствующего ему свободного экстента. Менеджер файловой системы выбирает из таблицы первый достаточно большой экстент.
В QNX файл может обозначаться более чем одним именем. Каждое имя файла называется связью. В действительности существует два вида связей: жесткие связи, или просто "связи", и символические связи. Символические связи описаны в следующей секции.
Для поддержки связей каждого файла, имя файла отделяется от остальной информации, описывающей файл. Эта информация хранится в структуре, называемой inode (индексным дескриптором).
Если файл имеет только одну связь (т.е. одно имя), то блок inode хранится в элементе каталога для этого файла. Но если файл имеет более чем одну связь, то inode хранится как запись в специальном файле /.inodes, а элемент каталога для файла содержит указатель на запись inode.
Учтите, что вы можете создать связь для файла, только если файл и связь находятся в одной и той же файловой системе.
Один и тот же файл обозначен двумя связями с именами "more" и "less".
Существует еще две ситуации, в которых для файла создается запись в файле /.inodes:
Если вы хотите: | Используйте: |
---|---|
Создать связь из командного интерпретатора | Утилиту ln |
Создать связь из программы | Функцию link() |
При создании файла, для него устанавливается счетчик связей, равный единице. По мере добавления ссылок этот счетчик увеличивается; при удалении связи счетчик связей уменьшается. Файл не удаляется с диска до того, как счетчик связей станет равным нулю и все программы, использующие этот файл, закроют его. Это позволяет использовать открытый файл даже после того, как у него удалены все связи.
Если вы хотите: | Используйте: |
---|---|
Удалить связь из командного интерпретатора | Утилиту rm |
Удалить связь из программы | Функции remove() или unlink() |
Вы не можете создавать жесткие связи для каталога. Однако каждый каталог имеет две жестко определенные связи:
Имя файла "точка" соответствует текущему каталогу; "точка точка" соответствует каталогу, предшествующему текущему каталогу.
Заметьте, что "точка точка" для каталога "/" - это просто "/", - вы не можете подняться выше.
Символическая связь - это особый файл, который содержит в качестве данных имя пути. Когда символическая связь используется в запросе ввода/вывода - например, open(), - обозначение связи в имени пути заменяется ее "данными". Символическая связь является гибким средством для перенаправления пути и часто используется для создания множества путей к одному и тому же файлу. В отличие от жестких связей, символические связи могут выходить за пределы файловой системы и также являться связями для каталогов.
В следующем примере каталоги //1/usr/fred и //2/usr/barney являются связями на один и тот же каталог, хотя они находятся в различных файловых системах, и даже на различных узлах (смотри следующую диаграмму). Это не может быть сделано с использованием жестких связей:
//1/usr/fred --> //2/usr/barney
Заметьте, что символическая связь и адресуемый каталог не обязаны иметь одно и то же имя. В большинстве случаев символические связи используются для привязки одного каталога к другому. Однако они также могут быть использованы для файлов, как в этом примере:
//1/usr/eric/src/test.c --> //1/usr/src/game.c
Если вы хотите: | Используйте утилиту: |
---|---|
Создать символическую связь | ln (с опцией -s) |
Удалить символическую связь* | rm |
Узнать, является ли файл символической связью | ls |
* Помните, что удаление символической связи действует только на связь, а не на адресуемый объект
Некоторые функции оперируют непосредственно с символическими связями. Для этих функций замена обозначения связи в пути на ее содержимое не производится. К этим функциям относятся unlink() (которая удаляет символическую связь), lstat() и readlink().
Так как символические связи могут указывать на каталоги, то неверная конфигурация может привести к проблемам, таким, как циклические связи. Чтобы защититься от циклических связей, система накладывает ограничения на количество переходов; этот предел определен как SYMLOOP_MAX во включаемом файле <limits.h>.
Программный канал - это неименованный файл, который служит как канал ввода/вывода между двумя или более взаимодействующими процессами - один процесс пишет в программный канал, другой читает из программного канала. Менеджер файловой системы обеспечивает буферизацию данных. Размер буфера определен как PIPE_BUF в файле <limits.h>. Программный канал удаляется после того как закрыты оба его конца.
Программные каналы обычно используются, когда два процесса хотят выполняться параллельно, с однонаправленной передачей данных от одного процесса к другому. Если требуется двунаправленная передача данных, то должны использоваться сообщения.
Типичное применение программного канала состоит в соединении вывода одной программы с вводом другой программы. Это соединение часто производится командным интерпретатором (Shell). Например:
ls | more
направляет стандартный вывод от утилиты ls через программный канал в стандартный ввод утилиты more.
Если вы хотите: | Используйте: |
---|---|
Создать программный канал из командного интерпретатора | Символ программного канала ("|") |
Создать программный канал из программы | Функции pipe() или popen() |
На бездисковых рабочих станциях вы можете запустить Менеджер программных каналов (Pipe) вместо Менеджера файловой системы, когда требуются только программные каналы. Менеджер программных каналов оптимизирован для канального (конвейерного) ввода/вывода и может обеспечить большую пропускную способность, чем Менеджер файловой системы. |
FIFO - это по существу то же самое, что и программные каналы, за исключением того, что FIFO являются именованными постоянными файлами, которые хранятся в каталогах файловой системы.
Если вы хотите: | Используйте: |
---|---|
Создать FIFO из командного интерпретатора | Утилиту mkfifo |
Создать FIFO из программы | Функцию mkfifo() |
Удалить FIFO из командного интерпретатора | Утилиту rm |
Удалить FIFO из программы | Функции remove() или unlink() |
Свойства Менеджера файловой системы, обеспечивающие высокопроизводительный доступ к диску:
Лифтовый поиск минимизирует общие затраты времени на позиционирование магнитной головки при чтении или записи на диск. Запросы ввода/вывода упорядочиваются таким образом, чтобы все они могли быть выполнены за один проход магнитной головки, от самого младшего к самому старшему адресу на диске.
Лифтовый поиск также имеет усовершенствование, обеспечивающее выполнение мультисекторного ввода/вывода там, где возможно.
Кэш-буфер - это интеллектуальный буфер между Менеджером файловой системы и драйвером диска. Кэш-буфер хранит блоки файлов с целью минимизировать количество обращений Менеджера файлов