Требуемые заголовки
,, , , .
Инс т рукци и по компиляции и компоновке программ
C++ -о program11-1 program11-1.cc
Среда для т ес ти рова ни я
Solaris 8, SuSE Linux 7.1.
Инструкции по выполнению
./program11-1
Компилятор gnuС++ также под д ерживает метод attach(). Этот мето д можно использовать д ля связи файловых д ескрипторов с объекта м и классов ifstreamи ofstream(листинг 11.21).
// Листинг 11.21. Подключение файловых дескрипторов к
// объекту класса ofstream
int main (int argc, char *argv[]) {
int Fd[2];
ofstream Out;
pipe(Fd);
Out.attach(Fd[l]); // - . .
// Межпроцессное взаимодействие. //. . .
Out.close( );
}
При вызове функции Out.attach(Fd[1]) объект класса ofstreamсвязывается с файловым дескриптором канала. Теперь Любая информация, которая будет помещена в объект Out,в действительности запишется в канал. Использование операторов извлечения и вставки для выполнения автоматического преобразования формата является основным достоинством использования семейства fstream-классов в сочетании с канальной связью. Возможность применять пользовательские средства извлечения и вставки избавляет программиста от определенных трудностей, которые могут иметь место при программировании каналов связи. Поэтому вместо явного перечисления размеров данных, записываемых в канал и читаемых из него, при управлении доступом для чтения-записи мы используем только количество передаваемых через канал элементов, что существенно упрощает весь процесс. К тому же такое «снижение себестоимости» немного упрощает параллельное программирование. Рекоменлуемый нами метод состоит в использовании архитектуры, в основе которой лежит принцип «разделяй и властвуй». Главное — правильно расставить компоненты «по своим местам» — и программирование станет более простым. Например, поскольку канал связывается с объектами классов ofstreamи ifstream,мы можем использовать информацию, хранимую компо н ентом ios,для определения состояния канала. Компоненты преобразования iostreams-классов можно использовать для выполнения автоматического преобразования данных, помещаемых в один конец канала и извлекаемых из его другого конца. Использование каналов вместе с iostream-классами также позволяет программисту интегрировать стандартные контейнеры и алгоритмы с использованием межпроцессного взаимодействия на основе канала. На рис. 11.9 показаны взаимоотношения между объектами классов ifstream, ofstream,каналом и средствами вставки и извлечения при организации межпроцессного взаимодействия.
Для чтения данных из канала и записи данных в канал можно также испо л ьзовать семейство к л ассов fstreamи функции-ч л ены read() и write ().
Доступ к анонимным каналам c использованием итератора ostream_iterator
Канал можно также испо л ьзовать с итераторами ostream_iteratorи istream_ iterator,которые представляют собой обобщенные объектно-ориентированные указатели. Итератор ostream_iteratorпозволяет передавать через канал целые контейнеры (т.е. списки, векторы, множества, очереди и пр.). Без использования iostreamo6beKTOB и итератора ostream_iterator передача контейнеров объектов была бы очень громоздкой и подверженной ошибкам процедурой. Операции, которые доступны для классов ostream_iterator и istream_iterator, перечислены в табл. 11.4.
Рис.11.9. Взаимоотношения между объектами классов ifstream, ofstream, каналом и средствами вставки и извлечения при организации межпроцессного взаимодействия |
Таблица»11.4. Операции, доступныедля классов ostream_iterator и istream_iterator
istream_iterator
а == b отношение эквивалентности
а != b отношение неэквивалентности
*a разыменовывание
++r инкремент (префиксная форма)
r++ инкремент (постфиксная форма)
ostream_iterator
++r инкремент (префиксная форма)
r++ инкремент (постфиксная форма)
Обычно эти итераторы используются вместе с iostreams-классами и стандартными алгоритмами. Итератор ostream_iterator предназначен только для последовательно выполняемой записи. После доступа к некоторому элементу программист не может вернуться к нему опять, не повторив всю итерацию сначала. При использовании этих итераторов канал обрабатывается как последовательный контейнер. Это означает, что при связывании канала с iostreams-объектами посредством итератора ostream_iterator и файловых дескрипторов мы можем применить стандартный алгоритм обработки данных для ввода их из канала и вывода их в канал. Причина того, что эти итераторы можно использовать вместе с каналами, состоит в связи, которая существует между итераторами и iostreams-классами. На рис. 11.10 представлена диаграмма, отображающая отношения между итераторами ввода-вывода и iostreams-классами.
Читать дальше