и чтении из него необязательно
Размеры блоков при записи в канал и чтении из него необязательно должны быть одинаковыми, хотя в нашем примере это и было так. Можно, например, писать в канал блоками по 512 байт, а затем считывать из него по одному символу, так же как и в случае обычного файла. Тем не менее, как будет показано в разделе 7.2, использование блоков фиксированного размера дает определенные преимущества.
Процесс
|
|
|
|
|
|
fdwrite()
|
fdw > >
|
|
|
|
v
|
fdread()
|
fdr < <
|
|
|
|
|
Рис. 7.1. Первый пример работы с каналами
Работа примера показана графически на рис. 7.1. Эта диаграмма позволяет более ясно представить, что процесс только посылает данные сам себе, используя канал в качестве некой разновидности механизма o6paтной связи. Это может показаться бессмысленным, поскольку процесс общается только сам с собой.
Настоящее значение каналов проявляется при использовании вместе с системным вызовом fork, тогда можно воспользоваться тем фактом, что файловые дескрипторы остаются открытыми в обоих процессах. Следующий пример демонстрирует это. Он создает канал и вызывает
fork, затем дочерний процесс обменивается несколькими сообщениями с родительским:
(* Второй пример работы с каналами *)
uses linux, stdio;
const
MSGSIZE=16;
msg1:array [0..MSGSIZE-1] of char = 'hello, world #1';
msg2:array [0..MSGSIZE-1] of char = 'hello, world #2';
msg3:array [0..MSGSIZE-1] of char = 'hello, world #3';
var
inbuf:array [0..MSGSIZE-1] of char;
fdr,fdw,j,pid:longint;
begin
(* Открыть канал *)
if not assignpipe (fdr,fdw) then
begin
perror ('Ошибка вызова pipe ');
halt (1);
end;
pid := fork;
case pid of
-1:
begin
perror ('Ошибка вызова fork');
halt (2);
end;
0:
begin
(* Это дочерний процесс, выполнить запись в канал *)
fdwrite (fdw, msg1, MSGSIZE);
fdwrite (fdw, msg2, MSGSIZE);
Содержание Назад Вперед