【问题标题】:execv, wait, Unix programming, How to wait for a childexecv, 等待, Unix 编程, 如何等待孩子
【发布时间】:2009-09-23 18:13:47
【问题描述】:

您好,我正在开发一个 unix shell,我遇到了两个问题。我想知道你们中是否有人可以帮助我。我的第一个问题是 shell 没有等待子进程终止。我实际上可以在子进程运行时输入更多命令。我的第二个问题在于以下两行。我在 shell 上没有任何显示。

    fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
    fprintf(stderr, "Child pid = %d\n", pid);

我有以下方法来执行用户输入的进程:即firefox、ls -a等

void execute(char *command[], char *file, int descriptor){
    pid_t pid;
    pid = fork();

    if(pid == -1){
        printf("error in execute has occurred\n");
    }
    if(pid == 0){           
        execvp(*command,command);
        fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
        fprintf(stderr, "Child pid = %d\n", pid);
        wait(&status);
            exit(EXIT_SUCCESS);
    }
    else{
        printf("ignore for now\n");
    }
}

这是我调用执行命令的地方。它工作正常并启动一个进程,但它不会等待它完成。

 execute(commandArgv, "STANDARD",0);

你们知道我做错了什么吗?谢谢,非常感谢您花时间帮助我。

【问题讨论】:

  • 我在执行调用后移动了等待。效果很好。谢谢。
  • 或者将其移至代码的“暂时忽略”部分,这是父级在子级被 fork()'d 后执行的操作。

标签: c unix wait execvp


【解决方案1】:

一旦 execvp() 运行,它将永远不会返回。它用提供的任何内容替换内存中正在运行的应用程序。所以你的 fprintf() 和 wait() 放错地方了。

【讨论】:

  • 重新阅读您的问题...也许您只需要调用 system() 来运行您的命令?还是你特别想fork+execvp?
【解决方案2】:

除了正确计算实际逻辑(Stéphane 的建议都很好)之外,您可能还希望在 fprintf-ing 之后执行 fflush(stderr),以确保您的错误消息立即显示出来,而不是被缓冲。

【讨论】:

    【解决方案3】:

    您在流程的运作方式上有一点错误。调用 execvp 后,没有回头路。 fork() 让您拥有父级和相同的子级,但 execvp 覆盖子级映像成为您正在调用的命令。

    execvp 返回仅在发生严重错误以防止覆盖图像时。因此,您需要在调用之前打印内容。因此,您可能还想在此处将 EXIT_SUCCESS 更改为 EXIT_FAILURE

    现在使用 wait 有另一个错误:您总是希望父母等待孩子,而不是相反。你不能要求孩子等待。她没有什么可等待的,她将运行并终止。因此,您需要将 wait() 调用移至 else 部分。

    void execute(char *command[], char *file, int descriptor)
    {
        pid_t pid;
        pid = fork();
    
        if(pid == -1)
        {
            printf("fork() error in execute() has occurred\n");
            return; /* return here without running the next else statement*/
        }
        if(pid == 0)
        {           
            fprintf(stderr, "Process name is: %s\n", commandArgv[0]);
            fprintf(stderr, "Child pid = %d\n", getpid());
            execvp(*command,command);
            fprintf(stderr, "Error! Can't overwrite child's image!\n");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("Parent waiting for child pid: %d\n", pid);
            wait(&status);
            printf("Parent running again\n");
        }
    }
    

    但是阅读您的问题,也许您实际上不希望父母等待。如果是这种情况,请不要使用 wait() 函数。

    保重, 贝科

    已编辑:一些小错误。孩子的pid是getpid()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 2021-04-28
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多