Размер канала и взоимодействие процессов при передаче данных

Буфер, связанный с каналом, имеет конечный размер. Минимальный размер канала – 512 байт. При попытке записать данные в уже заполненный канал, ядро заблокирует процесс до тех пор, пока другой процесс не считает из канала достаточное количество данных, чтобы заблокированный процесс смог возобновить запись. Таким образом ядро системы пытается организовать в канал запись данных неделимой порцией. Действия функции чтения более простые. При её выполнении проверяется является ли канал пустым, если пуст, то функция чтения блокируется до тех пор, пока другой процесс не запишет данные в канал. А если же функция чтения запрашивает больше данных, чем есть в канале, то завершает выполнение после прочтения имеющихся в канале данных, даже если их меньше, чем функция запрашивает.

Интересные моменты: если больше нет процессов, которые могли бы выполнить запись в канал и канал при этом пуст, то любой процесс, который попытается выполнить чтение из канала получит пустой блок, а процессы, которые ожидали чтения из канала продолжат свою работу, а их вызовы чтения вернут 0-ое значение; если больше нет про процессов, которые могли бы выполнить чтение из канала, то ядро опирационной системы посылает сигнал SIGPIPE всем процессам ожидающим запись. По умолчанию этот сигнал приведет к остановке процесса. А если его перехватят, то после завершения процесса обработки, функция записи вернет значение -1, а переменная errno получит код EPIPE.

#include<unistd.h>

#include<fcntl.h>

#include<stdio.h>

#define MSG_S 7

char *msg1=”Привет”;

char *msg2=”Пока”;

int perent(int p[2])

{ int n_r;

char buf[MSG_S];

close(p[1]);

for(;;)

{ switch(n_r=read(p[0],buf,MSG_S))

{ case -1: if(errno==EAGAIN)

{ printf(“Канал пуст\n”);

sleep(1);

}

else

{ printf(“Ошибка read\n”);

exit(1);

}

case 0: printf(“Конец связи\n”);

exit(0);

default: printf(“MSG=%s\n”,buf);

}

}

}

int child(int p[2])

{ int i;

close (p[0]);

for(i=0;i<3;i++)

{ write(p[1],msg1,MSG_S);

sleep(3);

}

write(p[1],msg2,MSG_S);

exit(0);

}

main()

{ int pdf[2];

if(pipe(pdf)==-1)

{ printf(”Ошибка pipe\n”);

exit(1);

}

fcntf(pdf[0],F_SETFL,O_NONBLOCK);

switch(fork())

{ case -1: exit(1);

case 0: child(pdf);

default: parent(pdf);

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: