std :: cin не блокируется, когда процесс разветвляется - PullRequest
1 голос
/ 07 апреля 2020

У меня есть консольное приложение C ++, которое разветвляется и закрывает основной процесс. std :: cin в дочернем процессе больше не блокируется при нажатии любой клавиши. Это приводит к бесконечному l oop. Если я не произвожу вилку раньше, приложение будет работать так, как ожидалось.

Я пробовал разные комбинации 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');
    }
}

1 Ответ

0 голосов
/ 07 апреля 2020

команды 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 % 
...