В C, можно ли читать из труб без ожидания, могут использоваться обратные вызовы или другие способы?

Я пытался прочитать из STDOUT разветвленного процесса. Однако, если я читаю из трубы в бесконечном for loop, он будет занят, даже если никакие данные не пройдут через трубу (пожалуйста, поправьте меня, если я ошибаюсь), и я предполагаю, что должен быть лучший способ делайте это иначе, чем использование sleep, если оно выполняется на коротких интервалах, может быть с обратными вызовами, о которых я не уверен. Ниже приведен фрагмент кода, который я пробовал.

pid_t pid = fork();  
switch (pid) {
    case 0:
        dup2 (pipes[1], STDOUT_FILENO );
        dup2(pipes[1], STDERR_FILENO); 
        close(pipes[0]); 
        close(pipes[1]);
        execv(path, args);
        break;
    default :
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        child_pid = pid;
        signal(SIGHUP, mysighandle);
        close(pipes[1]); 
        ssize_t nbytes;
        for (;;) {
            nbytes = read(pipes[0], buf, BUFSIZE); 
            if (nbytes == -1){
                break;
            }
            if (nbytes == 0) {
                break;
            }
            syslog(LOG_NOTICE, "%s", buf);

Может ли кто-нибудь предложить лучший способ без ожидания, который может использоваться для чтения данных из труб? Поскольку я новичок в C, любые ссылки на фрагменты кода оцениваются.

С уважением.

Ответ 1

В вашем коде вы не установили свой канал в неблокирующий режим (по крайней мере, я предполагаю, что вы этого не сделали, поскольку вы фактически не показываете, как вы его открываете), и поэтому read() делает чтение блокировки. То есть, если данных нет, но в каком-то процессе все еще есть открытый канал для записи, он автоматически приостанавливает процесс до тех пор, пока не будет доступно больше данных (и затем прочитает эти данные в буфере).

Таким образом, ваш код работает очень хорошо, как есть, и нет необходимости его изменять.

(То есть, если вы не хотите читать из нескольких труб одновременно или ждать данных, а также делать что-то еще в одном потоке, в этом случае вы действительно должны использовать select() и (возможно) неблокирующий ввод-вывод.)