【问题标题】:Why my program in which a child process is forked needs user to type 'Enter' before exiting?为什么我的子进程被分叉的程序需要用户在退出之前输入“Enter”?
【发布时间】:2020-03-21 09:34:24
【问题描述】:

我有以下程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/wait.h>

int main()
{
    int p[2];
    char *argv[2];
    argv[0] = "wc";
    argv[1] = "-w";
    argv[2] = NULL;

    pipe(p);
    if (fork() == 0)
    {
        close(0);
        dup(p[0]);
        close(p[0]);
        close(p[1]);
        execvp(argv[0], argv);
    }
    else
    {
        close(p[0]);
        write(p[1], "hello world\n", 12);
    }

    fprintf(stdout, "hello world\n");
}

当我运行它时:

$ gcc a.c
$ ./a.out

我得到了以下信息:

hello world
$ 2
_    // the cursor is flickering here

在我输入Enter 后,程序退出。这是什么原因?另外,如果我这样交换父进程和子进程中的内容:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/wait.h>

int main()
{
    int p[2];
    char *argv[2];
    argv[0] = "wc";
    argv[1] = "-w";
    argv[2] = NULL;

    pipe(p);
    if (fork() == 0)
    {
        close(p[0]);
        write(p[1], "hello world\n", 12);
    }
    else
    {
        close(0);
        dup(p[0]);
        close(p[0]);
        close(p[1]);
        execvp(argv[0], argv);
    }

    fprintf(stdout, "hello world\n");
}

我得到了预期的输出:

hello world
2
$

程序已退出并准备好获取下一个命令。第一个程序有什么问题?

【问题讨论】:

  • 一方面,你的char *argv[2] 需要是argv[3] 来保存你想要加上终止NULL指针的两个参数。
  • 后台wc的输出在提示后打印。您的 shell 正在等待您输入命令,例如,在打印出 2 后立即输入 ps 并查看正在运行的进程。
  • @JonathanLeffler 是的,这是真的。那个时候程序已经退出了。 wc 的输出出现在提示符之后。

标签: c linux pipe fork posix


【解决方案1】:

如果你仔细查看你的输出,你会发现你的程序已经退出了:

hello world
$ 2
_    // the cursor is flickering here

看看$ 是如何打印的?这是你的 shell 像往常一样等待输入。通过按enter,您刚刚在shell 中输入了一个空白命令并获得了第二个$ 提示符。

2 在那里做什么?那是wc 的输出。您的程序实际上并没有等待wc 退出。这意味着您的程序退出 before wc 确实如此,所以 shell 恢复,打印它的提示符,并且只有 then wc 退出并打印 2

要解决此问题,您可能需要添加某种wait 调用来等待父进程中的子进程。

【讨论】:

    猜你喜欢
    • 2011-01-21
    • 2021-03-23
    • 1970-01-01
    • 2015-12-12
    • 2019-04-23
    • 1970-01-01
    • 2021-04-26
    • 2020-08-03
    • 1970-01-01
    相关资源
    最近更新 更多