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.
我试图从分叉过程的STDOUT中读取。但是,如果我在无限循环中读取管道,即使没有数据通过管道也会忙着等待(如果我错了请纠正我),我想必须有更好的方法做除了使用睡眠,如果是短暂的间隔,可能是回调,我不确定。以下是我尝试过的代码片段。
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.
有人可以建议一个没有忙碌的更好的方法,可以用来从管道读取数据吗?由于我是C语言的初学者,所以对代码片段的任何引用都表示赞赏。
Regards.
1 个解决方案
#1
9
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).
在你的代码中,你没有将管道设置为非阻塞模式(至少,我假设你没有,因为你实际上没有显示你是如何打开它的),所以read()正在做阻止阅读。也就是说,如果没有可用的数据,但某些进程仍然打开管道进行写入,那么它将自动暂停您的进程,直到有更多数据可用(然后将该数据读入缓冲区)。
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.)
(也就是说,除非你想同时从多个管道中读取,或者在同一个线程中同时执行其他操作时等待数据,在这种情况下你确实应该使用select()和(可能)非阻塞I / O.)
#1
9
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).
在你的代码中,你没有将管道设置为非阻塞模式(至少,我假设你没有,因为你实际上没有显示你是如何打开它的),所以read()正在做阻止阅读。也就是说,如果没有可用的数据,但某些进程仍然打开管道进行写入,那么它将自动暂停您的进程,直到有更多数据可用(然后将该数据读入缓冲区)。
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.)
(也就是说,除非你想同时从多个管道中读取,或者在同一个线程中同时执行其他操作时等待数据,在这种情况下你确实应该使用select()和(可能)非阻塞I / O.)