Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I was trying to read from the STDOUT of a forked process. However, if I am reading from the pipe in an infinite for loop, it would be busy waiting even if no data is coming through the pipe (please correct me if I am wrong), and I guess there must be a better way to do it other than using sleep if it is for short intervals, may be with callbacks, which I am not sure about. The below is the code snippet that I tried.

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);

Can someone please suggest a better way without busywaiting, that could be used to read data from pipes? Since I am a beginner in C, any references to code-snippets are appreciated.

Regards.

like image 418
nohup Avatar asked Oct 24 '16 12:10

nohup


People also ask

How does pipe () work in C?

The pipe function creates a pipe and puts the file descriptors for the reading and writing ends of the pipe (respectively) into filedes [0] and filedes [1] . An easy way to remember that the input end comes first is that file descriptor 0 is standard input, and file descriptor 1 is standard output.

Is pipe read blocking?

Read/Write Are Blocking - when a process reads from a named pipe that has no data in it, the reading process is blocked. It does not receive an end of file (EOF) value, like when reading from a file.

Can more than 1 process write on pipe at a time?

Yes, multiple processes can read from (or write to) a pipe. But data isn't duplicated for the processes.


1 Answers

In your code, you haven't set your pipe to non-blocking mode (at least, I assume you haven't, since you don't actually show how you're opening it), and so read() is doing a blocking read. That is, if there is no data available, but some process still has the pipe open for writing, then it will automatically pause your process until more data is available (and will then read that data into the buffer).

Thus, your code works just fine as it is, and there's no need to change it.

(That is, unless you want to read from multiple pipes at the same time, or wait for data while also doing something else in the same thread, in which case you should indeed use select() and (possibly) non-blocking I/O.)

like image 116
Ilmari Karonen Avatar answered Oct 19 '22 08:10

Ilmari Karonen