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 чтобы обойти это, но в общем случае ваша программа не может изменить буферизацию потока вывода предыдущей программы в канале.

Другие вопросы по тегам