在C中,我们可以在没有忙碌的情况下从管道中读取,可能正在使用回调或其他方式吗?

noh*_*hup 10 c pipe busy-waiting

我试图从分叉过程的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);
Run Code Online (Sandbox Code Playgroud)

有人可以建议一个没有忙碌的更好的方法,可以用来从管道读取数据吗?由于我是初学者C,所以对代码片段的任何引用都很受欢迎.

问候.

Ilm*_*nen 9

在你的代码中,你没有将你的管道设置为非阻塞模式(至少,我认为你没有,因为你实际上没有显示你是如何打开它的),所以read()正在进行阻塞读取.也就是说,如果没有可用的数据,但某些进程仍然打开管道进行写入,那么它将自动暂停您的进程,直到有更多数据可用(然后将该数据读入缓冲区).

因此,您的代码可以正常工作,并且无需更改它.

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