write()
read()
Процесс
p[1]
p[0]
Рис. 5.1. Первый пример работы с каналами
Настоящее значение каналов проявляется при использовании вместе с системным вызовом fork, тогда можно воспользоваться тем фактом, что файловые дескрипторы остаются открытыми в обоих процессах. Следующий пример демонстрирует это – он создает канал и вызывает fork, затем дочерний процесс обменивается несколькими сообщениями с родительским:
#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:
/*Это дочерний процесс, выполнить запись в канал*/
write (p[1], msg1, MSGSIZE);
write (p[1], msg2, MSGSIZE);
write (p[1], msg3, MSGSIZE);
break;
default:
/*Это родительский процесс, выполнить чтение из канала*/
for (j=0; j<3; j++)
{
read (p[0], inbuf, MSGSIZE);
printf (“%s\n”, inbuf);
}
wait (NULL);
}
exit (0);
}
Этот пример представлен графически на рис. 5.2. На нем показано, как канал соединяет два процесса. Здесь видно, что и в родительском, и в дочернем процессах открыто по два дескриптора файла, позволяя выполнять запись в канал и чтение из него. Поэтому любой из процессов может выполнять запись в файл с дескриптором p[1] и чтение из файла с дескриптором p[0]. Это создает определенную проблему – каналы предназначены для использования в качестве однонаправленного средства связи. Если оба процесса будут одновременно выполнять чтение из канала и запись в него, то это приведет к путанице.
write()
Достарыңызбен бөлісу: |