gpt4 book ai didi

c++ - 在 C++ 中,当 cin 是 bash heredoc 时调用 fork 会导致重复输入片段

转载 作者:IT老高 更新时间:2023-10-28 23:21:38 25 4
gpt4 key购买 nike

我正在用 C++ 实现一个类似 shell 的程序。它有一个循环,从 cin 中读取、 fork 并等待子节点。

如果输入是交互式的或者是从另一个程序通过管道传输的,这可以正常工作。但是,当输入是 bash heredoc ,程序会重新读取部分输入(有时是无限期的)。

我了解子进程继承父进程的文件描述符,包括共享文件偏移量。但是,这个例子中的 child 没有从 cin 中读取任何内容,所以我认为它不应该触及偏移量。我有点不明白为什么会这样。


test.cpp:

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char **argv)
{
std::string line;
while (std::getline(std::cin, line)) {
pid_t pid = fork();
if (pid == 0) { // child
break; // exit immediately
}
else if (pid > 0) { // parent
waitpid(pid, nullptr, 0);
}
else { // error
perror("fork");
}

std::cout << getpid() << ": " << line << "\n";
}
return 0;
}

我编译如下:

g++ test.cpp -std=c++11

然后我运行它:

./a.out <<EOF
hello world
goodbye world
EOF

输出:

7754: hello world
7754: goodbye world
7754: goodbye world

如果我在输入命令中添加第三行 foo bar,程序就会陷入无限循环:

13080: hello world
13080: goodbye world
13080: foo bar
13080: o world
13080: goodbye world
13080: foo bar
13080: o world
[...]

版本:

  • Linux 内核:4.4.0-51-generic
  • Ubuntu:16.04.1 LTS(xenial)
  • bash:GNU bash,版本 4.3.46(1)-release (x86_64-pc-linux-gnu)
  • gcc: g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

最佳答案

我能够重现这个问题,不仅使用heredoc,还使用标准文件重定向。

这是我使用的测试脚本。在第一种和第二种情况下,我都得到了第二行输入的重复。

./a.out < Input.txt
echo

cat Input.txt | ./a.out
echo

./a.out <<EOF
hello world
goodbye world
EOF

在退出子进程之前关闭 stdin 似乎可以消除这两个问题。

#include <iostream>
#include <sstream>
#include <unistd.h>
#include <sys/wait.h>
#include <limits>

int main(int argc, char **argv)
{
std::string line;
while (std::getline(std::cin, line)) {
pid_t pid = fork();
if (pid == 0) { // child
close(STDIN_FILENO);
break; // exit after first closing stdin
}
else if (pid > 0) { // parent
waitpid(pid, nullptr, 0);
}
else { // error
perror("fork");
}

std::cout << getpid() << ": " << line << "\n";
}
return 0;
}

关于c++ - 在 C++ 中,当 cin 是 bash heredoc 时调用 fork 会导致重复输入片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40965628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com