【问题标题】:How to use fork in C?如何在 C 语言中使用 fork?
【发布时间】:2020-08-16 04:58:03
【问题描述】:

这里是完整的代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    char *command, *infile, *outfile;
    int wstatus;

    command = argv[1];
    infile = argv[2];
    outfile = argv[3];

    if (fork()) {
        wait(&wstatus);
        printf("Exit status: %d\n", WEXITSTATUS(wstatus));
    }
    else {
        close(0);
        open(infile, O_RDONLY);
        close(1);
        open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);
        execlp(command, command, NULL);

    }

    return 0;
}


这段代码应该分叉并执行一个带有 stdinstdout 重定向的命令,然后等待它终止并收到printf WEXITSTATUS(wstatus)。例如./allredir hexdump out_of_ls dump_file.

所以,我了解fork() 之前的一切。但我有以下问题:

  1. 据我了解,fork() 克隆了进程,但我不明白它是如何执行命令的,因为 execlp 应该这样做,而代码永远不会到达那部分。
  2. 我不明白execlp 的工作原理。为什么我们要向它发送两次命令 (execlp(command, command, NULL);)?
  3. 如果我们不通过outfileexeclp 如何知道将输出重定向到哪里。
  4. 如果命令已经作为另一个参数传递,为什么我们还需要infile

提前感谢您的回答。

【问题讨论】:

  • 您确定您的open 调用有效并返回了您期望的fds?一些asserts 会有所帮助。
  • 代码是否有效,您只是不明白如何,还是有问题?

标签: c fork


【解决方案1】:
  1. 据我了解,fork() 克隆了进程,但我不明白它是如何执行命令的,因为 execlp 应该这样做 并且代码永远不会到达那部分。

Fork 在父空间返回子进程的 pid,在新进程空间返回 0。子进程调用 execlp。

if (fork()) { 
    /* Parent process waits for child process */
}
else {
    /* Son process */
    execlp(command, command, NULL);
}

  1. 我不明白 execlp 的工作原理。为什么我们要向它发送两次命令 (execlp(command, command, NULL);)?

阅读execlp 手册页和this 线程

按照惯例,第一个参数应该指向文件名 与正在执行的文件相关联。


  1. 如果我们不向任何地方传递 outfile,execlp 如何知道将输出重定向到哪里。

重定向发生在关闭标准输入和标准输出文件描述符之前。通过打开文件描述符将容纳条目 0 和 1 的文件进行重定向。

else {
    /* redirecting stdin */
    close(0); 
    open(infile, O_RDONLY);  

    /* redirecting stdout */
    close(1); 
    open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);

    execlp(command, command, NULL);
}

  1. 如果命令已经作为另一个参数传递,为什么我们还需要一个 infile?

如果没有看到作为命令传递的参数,我们就无法判断您的程序做了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 2011-09-21
    • 2014-02-16
    • 2011-07-04
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    相关资源
    最近更新 更多