在 C 语言中,我们是否可以在不使用 busywaiting 的情况下从管道中读取数据,可能是使用回调或其他方式?

In C, can we read from pipes without busywaiting, may be using callbacks or other ways?

我试图从分叉进程的 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 的新手,任何对代码片段的引用都将受到赞赏。

此致。

在您的代码中,您尚未将管道设置为 non-blocking mode (at least, I assume you haven't, since you don't actually show how you're opening it), and so read() 正在执行阻塞读取。也就是说,如果没有可用数据,但某些进程仍然打开管道进行写入,那么它会自动暂停您的进程,直到有更多数据可用(然后将该数据读入缓冲区)。

因此,您的代码可以正常工作,无需更改。

(也就是说,除非您想同时从多个管道读取数据,或者在等待数据的同时还在同一个线程中执行其他操作,在这种情况下您确实应该使用 select() 和 (可能)非阻塞 I/O.)