C 从管道中读取所有数据
C reading all data from pipe
我的程序创建子进程并设置管道与其通信。当我尝试从管道读取数据时出现问题。由于子进程已经结束(我使用 wait
来确保)EOF 应该在数据流的末尾从而结束读取(如 pipe
的手册页中所示)。但是 read
只是冻结并等待更多数据的到来。
我在这里错过了什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void setfd(int *in, int *out) {
dup2(out[1], 1);
dup2(in[0], 0);
}
int main(int argc, char *argv[]) {
int status;
int pipe2ch[2], pipe2pr[2];
char *newargv[] = {NULL, NULL};
newargv[0] = argv[1];
pipe(pipe2ch);
pipe(pipe2pr);
setfd(pipe2pr, pipe2ch);
int a;
if (!(a = fork())) {
setfd(pipe2ch, pipe2pr);
execve(newargv[0], newargv, NULL);
exit(1);
} else {
printf("hello!\n");
fflush(stdout);
char str;
wait(&status);
while (read(pipe2pr[0], &str, 1) > 0) {
fprintf(stderr, "%c", str);
}
exit(0);
}
}
Since child process has ended (i use wait to ensure that) EOF should be on the end of the data stream thus ending the read (As in the man page for pipe).
我不确定你读过什么来暗示这一点。或者也许是你的措辞我不明白。 EOF
不是流中的字符。
But instead read just freezes and waits for more data to come. What am i missing here?
几件事。最重要的一个可能是,当进程分叉时,父进程的打开文件描述符的子副本与父进程一样引用内核底层 table 打开文件中的相同条目,每个条目都保持打开状态,直到 它上面的所有句柄都关闭了。子进程在退出时关闭它所有的文件描述符,但是两个管道的两端在父进程中保持打开状态,所以文件结束将不会向读者发出信号。每个进程都必须关闭它不使用或已完成使用的管道末端。
另外,你应该先read()
,然后wait()
,因为如果子进程向管道写入足够的数据那么它可能会阻塞,如果父进程直到子进程之后才读取退出然后你就会陷入僵局。
此外,我看不出有任何理由将任一管道端复制到父级的标准流中(导致关闭原始流)。只需通过管道的文件描述符来操作管道,就像您已经做的那样。如果你想要一个流接口,然后使用 fdopen()
来获得一个。
我的程序创建子进程并设置管道与其通信。当我尝试从管道读取数据时出现问题。由于子进程已经结束(我使用 wait
来确保)EOF 应该在数据流的末尾从而结束读取(如 pipe
的手册页中所示)。但是 read
只是冻结并等待更多数据的到来。
我在这里错过了什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void setfd(int *in, int *out) {
dup2(out[1], 1);
dup2(in[0], 0);
}
int main(int argc, char *argv[]) {
int status;
int pipe2ch[2], pipe2pr[2];
char *newargv[] = {NULL, NULL};
newargv[0] = argv[1];
pipe(pipe2ch);
pipe(pipe2pr);
setfd(pipe2pr, pipe2ch);
int a;
if (!(a = fork())) {
setfd(pipe2ch, pipe2pr);
execve(newargv[0], newargv, NULL);
exit(1);
} else {
printf("hello!\n");
fflush(stdout);
char str;
wait(&status);
while (read(pipe2pr[0], &str, 1) > 0) {
fprintf(stderr, "%c", str);
}
exit(0);
}
}
Since child process has ended (i use wait to ensure that) EOF should be on the end of the data stream thus ending the read (As in the man page for pipe).
我不确定你读过什么来暗示这一点。或者也许是你的措辞我不明白。 EOF
不是流中的字符。
But instead read just freezes and waits for more data to come. What am i missing here?
几件事。最重要的一个可能是,当进程分叉时,父进程的打开文件描述符的子副本与父进程一样引用内核底层 table 打开文件中的相同条目,每个条目都保持打开状态,直到 它上面的所有句柄都关闭了。子进程在退出时关闭它所有的文件描述符,但是两个管道的两端在父进程中保持打开状态,所以文件结束将不会向读者发出信号。每个进程都必须关闭它不使用或已完成使用的管道末端。
另外,你应该先read()
,然后wait()
,因为如果子进程向管道写入足够的数据那么它可能会阻塞,如果父进程直到子进程之后才读取退出然后你就会陷入僵局。
此外,我看不出有任何理由将任一管道端复制到父级的标准流中(导致关闭原始流)。只需通过管道的文件描述符来操作管道,就像您已经做的那样。如果你想要一个流接口,然后使用 fdopen()
来获得一个。