//...
int Fd[2];
Pipe(Fd);
ifstream IPipe(Fd[0]) ;
ofstream OPipe(Fd[1]) ;
будут созданы объектно-ориентированные каналы. Объект IPipeбудет играть роль входного потока, а объект OPipe—выходного. После создания эти потоки можно применять для связи между параллельно выполняемыми процессами с использованием потоково г о представления и операторов вставки (<<) и извлечения (>>). Для С++-сред, которые поддерживают метод attach(),дескриптор файла можно связать с объектами классов ifstream, ofstreamили fstream,используя следующий синтаксис.
// Листинг 11.20. Создание канала и использование
// функции attach()
int Fd[2];
ofstream OPipe;
//.. .
pipe(Fd);
//.. .
OPipe.attach(Fd[1]);
//.. .
OPipe << Value << endl;
Такой способ использования объектно-ориентированных каналов предполагает существование сыновнего процесса, который может считывать из них информацию. В программе 11.1 для создания двух процессов используется fork-инструкция. Родительский процесс отправляет значение сыновнему процессу с помощью iostreams-ориентированного канала.
// Программа 11.1
1 #include
2 #include
3 #include
4 #include
5 #include 6
7 8 9
10 int main(int argc, char *argv[])
11 {
12
13 int Fd[2];
14 int Pid;
15 float Value;
16 int Status;
17 if(pipe(Fd) != 0) {
18 cerr « «Ошибка при создании канала " « endl;
19 exit(l);
20 }
21 Pid = fork();
22 if(Pid == 0){
23 ifstream IPipe(Fd[0]);
24 IPipe » Value;
25 cout « «От процесса-родителя получено значение» << Value << endl;
26 IPipe.close();
27 }
28 else{
29 ofstream OPipe(Fd[l]);
30 OPipe « M_PI « endl;
31 wait(&Status);
32 OPipe.close();
33
34 }
35
36 }
Вспомните, что значение 0, возвращаемое функцией fork(),принадлежит сыновнему процессу. В программе 11.1 канал создается при выполнении инструкции, расположенной на строке 17. А при выполнении инструкции, расположенной на строке 29, родительский процесс открывает канал для записи. Файловый дескриптор Fd[1] означает «записывающий» конец канала. К этому концу канала (благо д аря вызову конструктора на строке 29) присоединяется объект класса ofstream.К «считывающему» концу канала присоединяется объект класса ifstream(строка 23). Сыновний процесс открывает канал для чтения и получает доступ к дескриптору файла, поскольку он вместе со средой родителя наслелует и дескрипторы файлов. Таким образом, любые файлы, которые открыты в среде родителя, будут оставаться открытыми и в среде наследника, если операционнал система не получит явные инструкции, основанные на системной функции fcntl.Помимо наследования открытых файлов, маркеры внутрифайловых позиций остаются там, где они были в момент порождения сыновнего процесса, чтобы сыновний процесс также получил доступ к маркеру позиции. При изменении позиции в родительском процессе маркер сыновнего также смещается. В этом случае мы могли бы реализовать потоковое представление данных, не создавал интерфейсный класс. Просто присоединив файловые дескрипторы канала к объектам классов ofstreamи ifstream,мы сможем использовать операторы вставки (<<) и извлечения (»). Аналогично любой класс, в котором определены операторы ">>" и "<<", может выполнять операции вставки данных в канал и извлечения их оттуда без какого-либо дополнительного программирования. В программе 11.1 родительский процесс поме щ ает значение M_PIв канал (строка 30), а сыновний процесс извлекает это з н ачение из канала, используя оператор ">>" (строка24). Инструкции по выполнению и компиляции этой программы приведены в разделе «Профиль программы 11.1».
f
(Профиль программы11.1
Имя программы program11-1.cc
Оп и сание
Программа 11.1 демонстрирует использование объектно-ориентированного потока c использованием анонимных системных каналов. Для создания двух процессов, |которые взаимодействуют между собой с помощью операторов вставки («) и из-!влечения (»), программа использует функцию fork().
Читать дальше