Linux без буферизации читает из STDIO
Я пытаюсь переписать дубликат wc -l
который отображает частичные результаты, так как он получает входные данные (например,
Моя текущая версия простая
while(!feof(in) &&
//(readc=fread(buf, 1,BUFSIZE,in))) {
(readc=read(0,buf, BUFSIZE))) {
for(i=0;i<readc;i++) {
lines += (buf[i] == '\n');
}
}
Проблема в том, что мой stdin
все еще получает буферизованный блок. Весь смысл этого упражнения в том, чтобы вывод не занимал ожидание заполнения каждого блока 4 КБ. Я полагаю, что буферизация строки будет в порядке.
Пример приложения: find | partial_wc
awk 'NR%1000==0 {printf "%d\r",NR} END {print NR}'
имеет аналогичный вывод, за исключением того, что я хотел бы выбрать вывод на основе времени (например, каждые 1 с), а не строк. Кроме того, это интересный вопрос для обучения.
Я попытался воспользоваться советом о том, почему grep работает быстро, но не могу понять, какой набор системных вызовов использовать.
2 ответа
Конечно, попробуйте API управления терминалом POSIX:
#include <termios.h>
struct termios ctrl;
tcgetattr(STDIN_FILENO, &ctrl);
ctrl.c_lflag &= ~ICANON; // turning off canonical mode makes input unbuffered
tcsetattr(STDIN_FILENO, TCSANOW, &ctrl);
Проблема не в том, что ваш stdin буферизируется в блоке, а в том, что стандартный вывод процесса, генерирующего ваши данные, буферизуется в блоке. Если вы контролируете всю цепочку процессов вашего канала передачи данных, вы можете использовать unbuffer
чтобы обойти это, но в общем случае ваша программа не может изменить буферизацию потока вывода предыдущей программы в канале.