我有一个C++控制台应用程序,该应用程序会自动 fork 并关闭主进程。
如果按任意键,则子进程中的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;
}

在此处添加注释的两行在这里是无用的,因为您读取了一个字符串,这在您读取例如数字而输入不是有效数字的情况下很有用

请注意,父进程在派生后立即退出,为子级关闭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++ - fork 进程时std::cin不阻塞,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61075110/

10-16 15:44