Pergunta

Sou meio novato no C ++ e trabalhando em um programa simples no Linux, que deve invocar outro programa no mesmo diretório e obter a saída do programa invocado sem mostrar a saída do programa invocado no console. Este é o trecho de código em que estou trabalhando:

    pid_t pid;
    cout<<"General sentance:"<<endl<<sentence<<endl;
    cout<<"==============================="<<endl;
    //int i=system("./Satzoo");
    if(pid=fork()<0)
        cout<<"Process could not be created..."<<endl;
    else
    {
        cout<<pid<<endl;
        execv("./Satzoo",NULL);
    }
    cout<<"General sentance:"<<endl<<sentence<<endl;
    cout<<"==============================="<<endl;

Um dos problemas que encontro é que sou capaz de imprimir as duas primeiras linhas no console, mas não consigo imprimir as duas últimas linhas. Acho que o programa para de funcionar quando invoco o programa Satzoo. Outra coisa é que esse código invoca o programa Satzoo duas vezes, não sei por quê? Eu posso ver a saída na tela duas vezes. Por outro lado, se eu usar o System () em vez de Execv (), o Satzoo funciona apenas uma vez.

Não descobri como ler a saída do Satzoo no meu programa.

Qualquer ajuda é apreciada.

Obrigado

Foi útil?

Solução

Você não está distinguindo entre a criança e o processo pai após a chamada para fork(). Então, tanto a criança quanto a mãe correm execv() e assim suas respectivas imagens de processo são substituídas.

Você quer algo mais como:

pid_t pid;
printf("before fork\n");

if((pid = fork()) < 0)
{
  printf("an error occurred while forking\n");
}
else if(pid == 0)
{
  /* this is the child */
  printf("the child's pid is: %d\n", getpid());
  execv("./Satzoo",NULL);
  printf("if this line is printed then execv failed\n");
}
else
{
  /* this is the parent */
  printf("parent continues execution\n");
}

Outras dicas

o fork() funções clones o processo atual e retorna diferente valores em cada processo. No processo "pai", ele retorna o PID da criança. No processo infantil, ele retorna zero. Então você normalmente invocaria usando um modelo como este:

if (fork() > 0) {
    cout << "in parent" << endl;
} else {
    cout << "in child" << endl;
    exit(0);
}

Eu omiti o manuseio de erros acima.

No seu exemplo, os dois caminhos de código acima (pai e filho) caem no else Cláusula de sua chamada para fork(), fazendo com que os dois execv("./Satzoo"). É por isso que seu programa funciona duas vezes e por que você nunca chega às declarações além disso.

Ao invés de usar fork() E fazer tudo manualmente (gerenciar corretamente a execução do processo é uma quantidade razoável de trabalho), você pode estar interessado em usar o popen() função em vez disso:

FILE *in = popen("./Satzoo", "r");
// use "in" like a normal stdio FILE to read the output of Satzoo
pclose(in);

De fork() MANPAGE:

VALOR DE RETORNO
Após a conclusão bem -sucedida, o Fork () retornará 0 ao processo filho e devolverá o ID do processo do processo filho ao processo pai. Ambos os processos devem continuar a executar a partir da função Fork (). Caso contrário, -1 deve ser devolvido ao processo pai, nenhum processo filho será criado e o ERRNO será definido para indicar o erro.

Você verifica para garantir que seja bem -sucedido, mas não se o pid indica que estamos na criança ou nos pais. Assim, tanto a criança quanto a mãe fazem a mesma coisa duas vezes, o que significa que seu programa é executado duas vezes e o texto final nunca será impresso. Você precisa verificar o valor de retorno de fork() mais do que apenas uma vez.

EXEC - A família de funções EXEC () substitui a imagem atual do processo por uma nova imagem de processo.

Sistema - Bloco na execução do comando. A execução do programa de chamada continua após o retorno do comando do sistema

Existem três testes de valor de retorno que você deseja com o garfo

  1. 0: você é a criança
  2. -1: erro
  3. outro: você é o pai

Você executou o outro programa da criança e do pai ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top