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.
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.
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.
Yes, multiple processes can read from (or write to) a pipe. But data isn't duplicated for the processes.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With