LINUX.ORG.RU

как сделать unbuffered pipe ?


0

0

собственно проблема тривиальная: есть приложение, которое выдает некие данные на stdout, есть другое приложение, которому надо эти данные получать ОПЕРАТИВНО, а не по заполнению буффера.. вобщем по пайпам я их связал, но буферизация всё ломает, как её отключить ?

PS: setbuff смотрел, но он устанавливает буффер стрима, а не "устройства", или я не прав?

anonymous

так не надо пользоваться stdio, раз не нужна
буферизация. использовать write().

"устройство" (pipe) здесь вообще не при чем, оно
и так unbuffered в этом смысле.

idle ★★★★★
()

> setbuff смотрел, но он устанавливает буффер стрима, а не "устройства", или я не прав?

Не прав, stdout и есть "стрим"

Можешь просто fflush(stdout) делать, когда надо данные передать

Die-Hard ★★★★★
()
Ответ на: комментарий от idle

дык! write и использую, read при этом возвращает данные только кодна буфер в 4k заполняется полностью

anonymous
()
Ответ на: комментарий от idle

pipe()
fork()

потомок: exec(pppd), пока не разобрался как он обращается с stdin/stdout, но надо думать у него всё ок, пока эмулирую его stdout посредствам write(stdout)

родитеть: использует read(), буферизация на лицо.

anonymous
()
Ответ на: комментарий от anonymous

pipe_read не будет блокировать процесс, если
можно считать хоть один байт, точка.

другое дело, что writer может напихать в pipe до 4096 байт
(пока есть свободное место) без переключения контекста, в
этом случае reader получит 4k за один прием в тот момент,
когда в pipe не останется свободного места, и writer
будет блокирован.

$ perl -e 'sleep 1,syswrite STDOUT,$_ for 0..5' | perl -le 'print $_ while sysread STDIN,$_,4096'
0
1
2
3
4
5

убираем sleep:

$ perl -e 'syswrite STDOUT,$_ for 0..5' | perl -le 'print $_ while sysread STDIN,$_,4096'
012345

anonymous
()
Ответ на: комментарий от anonymous

> другое дело, что writer может напихать в pipe до 4096 байт

то есть я имел в виду, что если процесс делает
write(pipe_fd, x, 1) reader будет разбужен, но cpu
он получит (и будет выполняться его read()) только
если у него приоритет больше, или у писателя кончился
timeslice. это для UP, конечно.

idle ★★★★★
()

Насколько я понял проблему....
В приложении , которое выдает на stdout, нужно сделать setbuf для stdout
примерно так
setbuf(stdout, NULL);
Это отключит буферизацию на stdout.

А read из pipe() ,действительно отдает все данные , даже если там один байт. Буферы у stream и pipe() абсолютно разные. У pipe этот буфер в ядре находится а у stream в userspace.



Dead ★★★★
()
Ответ на: комментарий от idle

с перлом - не иллюстративно, я пишу на С и у меня картина другая: реадер может что-то прочитать только после того, как буфер пайпа переполняется, а до этого - висит, выполняет селекты, выдает на экран бегущие символы... вобщем работает во всю и в использовании процессорного времени себе не отказывает ;)
я же пытаюсь найти способ передать потомку небуфферезированную пайпу или сделать её такой после передачи, чтобы его printf() попадал сразу же ко мне, а не сидел бы в буфере пайпа ;)

anonymous
()
Ответ на: комментарий от anonymous

>я же пытаюсь найти способ передать потомку небуфферезированную пайпу или сделать её такой после передачи, чтобы его printf() попадал сразу же ко мне, а не сидел бы в буфере пайпа ;)


Епрст.
Вопрос.
Почему ты решил что printf() сидит в буфере пайпа???
он сидит в буфере glibc, всмысле в буффере stream.
А это разные вещи.

Dead ★★★★
()
Ответ на: комментарий от anonymous

> чтобы его printf() попадал сразу же ко мне

кто говорил, что делает write() ??????

> с перлом - не иллюстративно, я пишу на С

похоже, вы не понимаете, о чем я говорю.

idle ★★★★★
()
Ответ на: комментарий от Dead

Пример

printf("abc");

напечатает на экран abc не сразу

а
printf("abc\n");
напечатает сразу


сравни две программы, сразу это заметишь

int main(void)
{

setbuf(stdout,NULL);
printf("aaaaa");
sleep(3);
printf("aaaaa\n");
return 0;
}


int main(void)
{
printf("aaaaa");
sleep(3);
printf("aaaaa\n");
return 0;
}


Dead ★★★★
()
Ответ на: комментарий от idle

> кто говорил, что делает write() ??????
я уж чего только не далал ;)

всем спасибо!
нашел PPPoE - делает почти тоже, что собираюсь делать я, буду разбираться на его примере ;)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.