在while循环中使用execvp和fork时的无限循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在while循环中使用execvp和fork时的无限循环相关的知识,希望对你有一定的参考价值。

我正在尝试编写一个小shell程序,我希望它在调用另一个程序后通过execvp()保持活动状态。我希望fork系统调用“复制”该过程,创建一个几乎相同的发布(父)进程的副本(子)。因此,当父母因为excevp()呼叫而终止时,孩子们将仍然活着。

在下面附带的代码中,我读了一个用户输入(程序和要执行的参数),然后我希望父fork将执行程序,子fork将等待用户的下一个输入,但是在第一次之后我插入输入(要执行的程序及其参数),程序陷入无限循环。当子fork获得控制权时,它执行前一个程序并且不等待新的输入(似乎在第一个fgets()之后它不再等待用户输入)。

这是代码中有问题的部分:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "LineParser.h"
#include <limits.h>
#include <unistd.h>

char buf[PATH_MAX];
char buf_user[2048];
int pid;

void execute(cmdLine* pCmdLine) {
   int pid = fork();
   if(pid != 0) {
     printf("I'm the parent.
");
       if(execvp(pCmdLine->arguments[0], pCmdLine->arguments) == -1) {
         perror("execute failed");
         _exit(1);
       }
   } else {
     freeCmdLines(pCmdLine);        
   }
}

int main(int argc, char *argv[])
{  
    while(1) {
        getcwd(buf, PATH_MAX);
        printf("%s> ", buf);
        fgets(buf_user, 2048, stdin);
        fflush(stdin);
        if(strcmp(buf_user, "quit
") == 0) {
            exit(0);
        }
        cmdLine* parsedCmd = parseCmdLines(buf_user);
        execute(parsedCmd);
    }
    return 0;
}

cmdLine结构:

#define MAX_ARGUMENTS 256

typedef struct cmdLine
{
    char *const arguments[MAX_ARGUMENTS]; /* command line arguments (arg 0 is the command) */
    int argCount;       /* number of arguments */
    char const *inputRedirect;  /* input redirection path. NULL if no input redirection */
    char const *outputRedirect; /* output redirection path. NULL if no output redirection */
    char blocking;  /* boolean indicating blocking/non-blocking */
    int idx;                /* index of current command in the chain of cmdLines (0 for the first) */
    struct cmdLine *next;   /* next cmdLine in chain */
} cmdLine;

/* Parses a given string to arguments and other indicators */
/* Returns NULL when there's nothing to parse */ 
/* When successful, returns a pointer to cmdLine (in case of a pipe, this will be the head of a linked list) */
cmdLine *parseCmdLines(const char *strLine);    /* Parse string line */

/* Releases all allocated memory for the chain (linked list) */
void freeCmdLines(cmdLine *pCmdLine);       /* Free parsed line */

/* Replaces arguments[num] with newString */
/* Returns 0 if num is out-of-range, otherwise - returns 1 */
int replaceCmdArg(cmdLine *pCmdLine, int num, const char *newString);
答案

你不应该在父母身上,而应该在孩子身上。

您的终端等待父母完成。完成父母而不等待它的孩子结束导致zombie process

修改代码以便在子代中执行命令并等待它在父代完成时解决了我测试时的问题。

我建议你看看男人3等!

以上是关于在while循环中使用execvp和fork时的无限循环的主要内容,如果未能解决你的问题,请参考以下文章

使用 fork() 和 execvp() 函数创建 C 程序时遇到问题

C - 内部带有 fork() / pipe() 的 WHILE 循环

JS中,for和while在使用时的区别。

pthread并在C中递归调用execvp

linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)

如何在Visual Studio 2015中使用fork()? (Windows 7专业版)