std::cin 进程分叉时未阻塞
std::cin is not blocking when process is forked
我有一个 C++ 控制台应用程序,它会自行分叉并关闭主进程。
如果按任意键,子进程中的 std::cin 不再阻塞。这导致无限循环。如果我之前没有分叉,那么应用程序会按预期运行。
我尝试了 cin::ignore、cin::fail、cin::clear 和 close 的不同组合来修复此问题,但没有成功。
我正在使用 Ubuntu 18.04.
为什么会发生这种情况,我该如何解决?
/* includes */
#include <iostream>
#include <unistd.h>
#include <limits>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(true)
{
std::cin >> commands;
std::cout << "Loop" << std::endl;
//std::cin.clear();
//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
std::cin >> 命令; 到达 EOF 时不会阻塞,您可以看到它检查是否 >> 成功,例如
if (! std::cin >> commands) {
std::cout << "EOF" << std::endl;
break;
}
您在评论中输入的两行在这里没有用,因为您读取的是一个字符串,它们在您读取一个数字而输入的不是有效数字的情况下很有用
注意父进程在 fork 之后立即退出,为子进程关闭 stdin 因为它们共享 stdin
如果我将您的程序修改为:
/* includes */
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <limits>
#include <sys/wait.h>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
waitpid(f_return, NULL, 0); // wait end of child
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(std::cin >> commands)
{
std::cout << commands << std::endl;
std::cout << "Loop" << std::endl;
}
std::cout << "done" << std::endl;
}
编译与执行:
/tmp % g++ -Wall f.cc
/tmp % echo "aze qsd" | ./a.out
aze
Loop
qsd
Loop
done
/tmp %
我有一个 C++ 控制台应用程序,它会自行分叉并关闭主进程。 如果按任意键,子进程中的 std::cin 不再阻塞。这导致无限循环。如果我之前没有分叉,那么应用程序会按预期运行。
我尝试了 cin::ignore、cin::fail、cin::clear 和 close 的不同组合来修复此问题,但没有成功。
我正在使用 Ubuntu 18.04.
为什么会发生这种情况,我该如何解决?
/* includes */
#include <iostream>
#include <unistd.h>
#include <limits>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(true)
{
std::cin >> commands;
std::cout << "Loop" << std::endl;
//std::cin.clear();
//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
std::cin >> 命令; 到达 EOF 时不会阻塞,您可以看到它检查是否 >> 成功,例如
if (! std::cin >> commands) {
std::cout << "EOF" << std::endl;
break;
}
您在评论中输入的两行在这里没有用,因为您读取的是一个字符串,它们在您读取一个数字而输入的不是有效数字的情况下很有用
注意父进程在 fork 之后立即退出,为子进程关闭 stdin 因为它们共享 stdin
如果我将您的程序修改为:
/* includes */
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <limits>
#include <sys/wait.h>
void fork_to_background()
{
pid_t f_return = fork();
if (f_return == -1)
{
exit(1);
}
if (f_return != 0)
{
waitpid(f_return, NULL, 0); // wait end of child
exit(0);
}
}
int main(int argc, char** argv)
{
fork_to_background();
std::string commands;
while(std::cin >> commands)
{
std::cout << commands << std::endl;
std::cout << "Loop" << std::endl;
}
std::cout << "done" << std::endl;
}
编译与执行:
/tmp % g++ -Wall f.cc
/tmp % echo "aze qsd" | ./a.out
aze
Loop
qsd
Loop
done
/tmp %