Головной модуль
Головной модуль
Обработку системных вызовов процессов осуществляет головной модуль. Головной модуль потока является единственным местом, где возможно блокирование обработки и, соответственно, процесса, в контексте которого осуществляется операция ввода/вывода. Головной модуль является внешним интерфейсом потока, и хотя его структура похожа на структуру обычного модуля, функции обработки здесь обеспечиваются самой подсистемой STREAMS. В отличие от точек входа в модуль или драйвер потока, реализующих специфическую для данного устройства обработку, функции головного модуля выполняют ряд общих для всех потоков задач, включающих:
? Трансляцию данных, передаваемых процессом с помощью системных вызовов, в сообщения и передачу их вниз по потоку.
? Сообщение об ошибках и отправление сигналов процессам, связанным с потоком.
? Распаковку сообщений, переданных вверх по потоку, и копирование данных в пространство ядра или задачи.
Процесс передает данные потоку с помощью системных вызовов write(2) и putmsg(2). Системный вызов write(2), представляющий собой унифицированный интерфейс передачи данных любым устройствам, позволяет производить передачу простых данных в виде потока байтов, не сохраняя границы логических записей. Системный вызов putmsg(2), предназначенный специально для работы с потоками, позволяет процессу за один вызов передать управляющее сообщение и данные. Головной модуль преобразует эту информацию в единое сообщение с сохранением границ записи.
Системный вызов putmsg(2) имеет вид:
#include <stropts.h>
int putmsg(int fildes, const struct strbuf *ctlptr,
const struct strbuf* dataptr, int flags);
С помощью этого вызова головной модуль формирует сообщение, состоящее из управляющей части M_PROTO и данных, передаваемых в блоках M_DATA. Содержимое сообщения передается с помощью указателей на структуру strbuf — ctlptr для управляющего блока и dataptr для блоков данных.
Структура strbuf имеет следующий формат:
struct strbuf {
int maxlen;
int len;
void *buf;
}
где maxlen не используется, len — размер передаваемых данных, buf — указатель на буфер.
С помощью аргумента flags процесс может передавать экстренные сообщения, установив флаг RS_HIPRI.
В обоих случаях головной модуль формирует сообщение и с помощью функции canput(9F) проверяет, способен ли следующий вниз по потоку модуль, обеспечивающий механизм управления передачей, принять его. Если canput(9F) возвращает истинный ответ, сообщение передается вниз по потоку с помощью функции putnext(9F), а управление возвращается процессу. Если canput(9F) возвращает ложный ответ, выполнение процесса блокируется, и он переходит в состояние сна, пока не рассосется образовавшийся затор. Заметим, что возврат системного вызова еще не гарантирует, что данные получены устройством. Возврат из write(2) или putmsg(2) свидетельствует лишь о том, что данные были успешно скопированы в адресное пространство ядра, и в виде сообщения направлены вниз по потоку.
Процесс может получить данные из потока с помощью системных вызовов read(2) и getmsg(2). Стандартный вызов read(2) позволяет получать только обычные данные без сохранения границ сообщений.[63] В отличие от этого вызова getmsg(2) позволяет получать данные сообщений типов M_DATA и M_PROTO, при этом сохраняются границы сообщений. Например, если полученное сообщение состоит из блока M_PROTO и нескольких блоков M_DATA, вызов getmsg(2) корректно разделит сообщение на две части: управляющую информацию и собственно данные.
Вызов getmsg(2) имеет вид:
#include <stropts.h>
int getmsg(int fildes, struct strbuf *ctlptr,
struct strbuf *dataptr, int *flagsp);
С помощью вызова getmsg(2) прикладной процесс может получить сообщение, причем его управляющие и прикладные данные будут помещены в буферы, адресуемые ctlptr и dataptr соответственно. Так же как и в случае putmsg(2) эти указатели адресуют структуру strbuf, которая отличается только тем, что поле maxlen определяет максимальный размер буфера, a len устанавливается равным фактическому числу полученных байтов. По умолчанию getmsg(2) получает первое полученное сообщение, однако с помощью флага RS_HIPRI, установленного в переменной, адресуемой аргументом flagsp, процесс может потребовать получение только экстренных сообщений.
В обоих случаях, если данные находятся в головном модуле, ядро извлекает их из сообщения, копирует в адресное пространство процесса и возвращает управление последнему. Если же в головном модуле отсутствуют сообщения, ожидающие получения, выполнение процесса блокируется, и он переходит в состояние сна до прихода сообщения.
Когда головной модуль получает сообщение, ядро проверяет, ожидает ли его какой-либо процесс. Если такой процесс имеется, ядро пробуждает процесс, копирует данные в пространство задачи и производит возврат из системного вызова. Если ни один из процессов не ожидает получения сообщения, оно буферизуется в очереди чтения головного модуля.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Модуль
Модуль Модули – это группы элементов, объединенные для создания отдельных блоков по принципу единства формы или функции. Форма регистрации, например, представляет собой модуль, объединяющий множество элементов, – метки поля формы, кнопки и
Модуль UDP
Модуль UDP Вернемся к рассмотрению ситуации, когда датаграмма адресована нашему хосту, не содержит ошибок (по крайней мере, с точки зрения IP) и должна быть передана транспортному протоколу. Поскольку целью данного раздела является иллюстрация схемы взаимодействия между
Модуль TCP
Модуль TCP Как следует из предшествующего описания TCP, этот транспортный протокол обеспечивает гораздо более высокое качество передачи, чем UDP. Соответственно, его реализация также является гораздо более сложной. В предыдущих разделах уже встречались различные алгоритмы,
Модуль INPUT
Модуль INPUT Ключевой концепцией, которую мы использовали начиная с первого дня, была идея входного потока с одним предсказывающим символом. Все подпрограммы синтаксического анализа проверяют этот символ, не изменяя его, чтобы решить, что они должны делать дальше.
14.9.6. Модуль Etc
14.9.6. Модуль Etc Модуль Etc получает различную информацию из файлов /etc/passwd и /etc/group. Понятно, что полезен он только на платформе UNIX.Метод getlogin возвращает имя пользователя, от имени которого запущена программа. Если он завершается неудачно, может помочь метод getpwuid (принимающий в
19.7.1. Модуль mod_ruby
19.7.1. Модуль mod_ruby Обычно, если CGI-сценарий пишется на интерпретируемом языке, то при каждом запросе загружается новый экземпляр интерпретатора. Это дорого обходится с точки зрения потребления ресурсов сервера и времени выполнения.Сервер Apache решает эту проблему путем
Модуль GraphABC
Модуль GraphABC Модуль GraphABC представляет собой простую графическую библиотеку и предназначен для создания несобытийных графических и анимационных программ в процедурном и частично в объектном стиле. Рисование осуществляется в специальном графическом окне, возможность
Модуль ABCObjects
Модуль ABCObjects Модуль ABCObjects: обзор Модуль ABCObjects реализует векторные графические объекты с возможностью масштабирования, наложения друг на друга, создания составных графических объектов и многократного их вложения друг в друга. Каждый векторный графический объект
Модуль ABCSprites
Модуль ABCSprites Модуль ABCSprites реализует спрайты - анимационные объекты с автоматически меняющимися кадрами. Спрайт представляется классом SpriteABC и является разновидностью мультикартинки MultiPictureABC, однако, обладает двумя дополнительными возможностями:1. Спрайты
Чистая энергия: трудный возраст. Почему солнечные и ветряные электростанции стали головной болью? Евгений Золотов
Чистая энергия: трудный возраст. Почему солнечные и ветряные электростанции стали головной болью? Евгений Золотов Опубликовано 04 октября 2013 Двадцать лет назад альтернативная энергетика была голубой мечтой — о чистом воздухе и бесконечных
Головной мозг растет вместе с социальным окружением
Головной мозг растет вместе с социальным окружением А как обстоят дела с взаимосвязью между размером зон головного мозга, ответственных за нашу жизнь в социуме, и размером нашего окружения? Чтобы окончательно внести ясность, следовало бы провести долговременный
Что именно растет, когда растет головной мозг?
Что именно растет, когда растет головной мозг? Головной мозг новорожденного представляет собой примерно одну четвертую часть (350 г) от веса и размера головного мозга взрослого человека (1300–1400 г); хотя и нервные клетки, и их соединительные волокна уже сформированы, и их
Тренировать головной мозг, чтобы бороться с его распадом
Тренировать головной мозг, чтобы бороться с его распадом Именно потому, что головной мозг — наш самый пластичный, самый гибкий орган, предназначенный для самообразования от колыбели до самой смерти, наши шансы внести существенный вклад в собственное духовное здоровье