c - popen2() 如何在 c 中工作?

标签 c pipe fork dup2

我正在尝试使用管道、fork 和 dup 在我的程序中执行 md5sume 命令。我找到了成功运行的求和代码,但我无法理解某些代码行。这是我的代码:

int infp, outfp;

char buf[128];

if (popen2("md5sum", &infp, &outfp) <= 0)

  {

    printf("Unable to exec sort\n");

    exit(1);

  }

write(infp, "hello\n", 2);

close(infp);

*buf = '\0';

read(outfp, buf, 128);

printf("buf = '%s'\n", buf);

return 0;

}

int p_stdin[2], p_stdout[2];

pid_t pid;

if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)

  return -1;

pid = fork();

if (pid < 0)

  return pid;

if (pid == 0)

  {

    close(p_stdin[WRITE]);

    dup2(p_stdin[READ], READ);

    close(p_stdout[READ]);

    dup2(p_stdout[WRITE], WRITE);

    execl("/bin/sh", "sh", "-c", command, NULL);

    perror("execl");

    exit(1);

  }

else 

  {

if (infp == NULL)

    close(p_stdin[WRITE]);

else

    *infp = p_stdin[WRITE];

if (outfp == NULL)

    close(p_stdout[READ]);

else

    *outfp = p_stdout[READ];
  }

return pid;

}

我不明白 popen 函数。这条线到底做了什么?

*infp = p_stdin[WRITE];

管道如何相互通信?

最佳答案

i dont understand the popen function.

how can pipes comunicate with each other?

pipe() :管道是单向的,是内核中的字节流缓冲区。由于它是字节流类型,写入者可以写入任意数量的字节,读取者可以读取任意数量的字节。但是,请注意顺序读取是可能的,但查找(如 lseek)是不可能的。由于管道是单向的,因此写入管道的数据应在内核中进行缓冲,直到从管道的读端读取为止。此外,如果管道变满,写入会阻塞。

假设 fd 是一个包含 2 个文件描述符 (int fd[2]) 的整数数组,那么 pipe(fd) 系统调用将创建一个管道并返回一对文件描述符,使得 fd[1] (stdout is 1) 应为管道的写入端,fd[0](stdin 为 0)应为管道的读取端。与命名管道(如 FIFO - 文件系统中具有名称的管道)不同,匿名管道只能在相关进程(如父子进程)之间使用。因此,应该执行 fork 以在子级中复制这 2 个父文件描述符,从而父级与子级共享管道,以便子级写入写端,父级从管道的读端读取,或者父级写入写- end 和 child 应从管道的读端读取。应注意确保父或子根据场景关闭未使用的读(fd[0])文件描述符/未使用的写(fd[1])文件描述符。

popen() : popen 使您能够将另一个程序作为新进程调用,从而向它传输数据或从它接收数据。在 popen 的情况下,请注意数据流的方向基于第二个参数。我们不需要手动创建子进程,因为 popen 会自动创建子进程,启动 shell 并执行通过 popen 传递的命令参数。它还根据类型参数自动在父子之间建立适当的读取或写入流。

因此,popen() 简化了事情,因为它避免了手动调用/调用 pipe、fork、exec 的需要,并简化了根据参数类型自动在父/子之间建立适当的流。然而,popen 的另一面是,应该注意的是,每次调用 popen() 都会导致创建额外的进程——也就是说,除了被调用的程序之外,每次都会调用 shell—— turn 导致高资源消耗。

关于c - popen2() 如何在 c 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33520838/

相关文章:

c - C中的声明与定义

c - 使用 C 将 char * 传递给 fopen

c - 兄弟子进程之间的管道份额

c - 使用 pipe() : How do I allow multiple child processes to execute simultaneously

c - fork 调用不执行子代码

c - 如何在 C 中使用 fork 写入和读取文件

c - `__noinline__` GLib和CUDA宏冲突

C栈数组问题

c - Linux fork、信号量、管道与 C

python - pexpect 多线程程序在生成 shell 时挂起