read()
Дочерний процесс
p[1]
p[0]
write()
read()
Родительский процесс
p[1]
p[0]
Рис. 5.2. Второй пример работы с каналами.
Чтобы избежать этого, каждый процесс должен выполнять либо чтение из канала, либо запись в него и закрывать дескриптор файла, как только он стал не нужен. Фактически программа должна выполнять это для того, чтобы избежать неприятностей, если посылающий данные процесс закроет дескриптор файла, открытого на запись. Приведенные до сих пор примеры работают только потому, что принимающий процесс в точности знает, какое количество данных он может ожидать. Следующий пример представляет собой законченное решение:
#include
#include
#define MSGSIZE 16
char *msg1 = “hello, world #1”;
char *msg2 = “hello, world #2”;
char *msg3 = “hello, world #3”;
main ()
{
char inbuf [MSGSIZE];
int p [2], j;
pid_t pid;
/*Открыть канал*/
if (pipe (p) == -1) {
perror (“Ошибка вызова pipe”);
exit (1);
}
switch (pid = fork ()) {
case -1:
perror (“Ошибка вызова fork”);
exit (2);
case 0:
/*Дочерний процесс, закрывает дескриптор файла,*/
/*открытого для чтения, и выполняет запись в канал*/
close (p[0]);
write (p[1], msg1, MSGSIZE);
write (p[1], msg2, MSGSIZE);
write (p[1], msg3, MSGSIZE);
break;
default:
/*Родительский процесс, закрывает дескриптор файла,*/
/*открытого для записи, и выполняет чтение из канала*/
close (p[1]);
for (j=0; j<3; j++)
{
read (p[0], inbuf, MSGSIZE);
printf (“%s\n”, inbuf);
}
wait (NULL);
}
exit (0);
}
В конечном итоге получится однонаправленный поток данных от дочернего процесса к родительскому. Эта упрощенная ситуация показана на рис. 5.3.
write()
Дочерний процесс
Достарыңызбен бөлісу: |