Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 294

Пять из семи базовых компонентов нашего потока уже реализованы в библиотеке классов iostreams. Поэтому нам остается лишь дополнить их компонентами портов ввода и вывода. Для этого мы можем рассмотреть системные средства поддержки потоков. В среде UNIX/Linux создать канал можно с помощью вызовов системных функций (листинг 11.19).

>// Листинг 11.19. Использование системного вызова для

>// создания канала

>int main(int argc, char *argv[]) {

>//.. .

>int Fd[2];

>pipe(Fd);

>//.. .

>}

Функция pipe () предназначена для создания структуры данных канала, которую можно использовать для взаимодействия между родительским и сыновним процессами. При успешном обращении к функции pipe () она возвращает два дескриптора файла. (Дескрипторы файлов представляют собой целые значения, которые используются для идентификации успешно открытых файлов.) В этом случае дескрипторы сохраняются в массиве Fd. Элемент Fd[0] используется при открытии файла для чтения, а элемент Fd[1] — при открытии файла для записи. После создания эти два дескриптора файлов можно использовать при вызове функций read() и write(). Функция write() обеспечивает вставку данных в канал посредством дескриптора Fd[1], а функция read() — извлечение данных из канала посредством дескриптора Fd[0]. Поскольку функция pipe () возвращает дескрипторы файлов, доступ к каналу можно получить с помощью системных средств работы с файлами. Для определения максимально возможного количества доступных дескрипторов файлов, открытых одним процессом, можно использовать системную функцию sysconf(_SC_OPEN_MAX), адля определения размера канала — функцию pathconf(_PC_PIPE_BUF).

Эти два файловых дескриптора представляют наши логические порты ввода и вывода соответственно. Мы также используем их для связи с библиотекой классов iostreams. В частности, они обеспечивают связь с классом буфера. Ко м понент буфера iostreams-классов имеет три семейства классов. Эти три типа буферных классов перечислены в табл. 11.3.

Таблица 11.3. Три типа буферных классов

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

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

basic_filebuf Связывает входные и выходные последовательности символов с файлом

Рассмотрим подробнее класс basic_filebuf. Тогда как класс basic_streambuf используется в качестве объектно-ориентированного буфера в операциях ввода-вывода с применением стандартного потока, а класс basic_stringbuf — в качестве объектно-ориентированного буфера для памяти, класс basic_filebuf применяется в качестве объектно-ориентированного буфера для файлов. Рассмотрев интерфейс для класса basic_filebuf и интерфейс для классов преобразования (basic_ifstream, basic_ofstream и basic_fstream), можно найти способ связать дескрипторы файлов, возвращаемые системной функцией pipe (), с объектами класса basic_iostream. На рис. 11.8 показаны диаграммы классов для семейства fstream-классов.