popen2() 在 c 中如何工作? [英] how does popen2() work in c?

查看:60
本文介绍了popen2() 在 c 中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用管道、叉和 dup 在我的程序中执行 md5sume 命令.我发现 sum 代码成功运行,但我无法理解某些代码行.这是我的代码:

im trying to execute md5sume command in my programm using pipe,fork and dup.i found sum code that run succesfully but i cant understand some line of code. Here is my code:

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 函数.这条线到底是做什么的?

i dont understand the popen function. What does this line exactly do?

*infp = p_stdin[WRITE];

管道如何相互通信?

推荐答案

我不明白 popen 函数.

i dont understand the popen function.

管道如何相互通信?

pipe() : 管道是单向的,是内核中的字节流缓冲区.由于它是字节流类型,因此写入器可以写入任意数量的字节,读取器可以读取任意数量的字节.但是,请注意顺序读取是可能的,但seek(如lseek)是不可能的.由于管道是单向的,写入管道的数据会缓存在内核中,直到从管道的读端读取.此外,如果管道已满,则写入会阻塞.

pipe() : A pipe is unidirectional and a byte stream buffer in kernel. As it is of type byte stream, a writer can write in arbitrary number of bytes and reader can read out arbitrary number of bytes. However, note that sequential reads are possible , but seek (like lseek) is not possible. Since pipe is uni-directinal, the data that is written into pipe shall be buffered in kernel, until it is read from the read-end of the pipe. Also, if pipe gets full, the write blocks.

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

Let's consider that fd is an integer array of 2 file descriptors (int fd[2]), then the pipe(fd) system call shall create a pipe and return a pair of file descriptors such that fd[1] (stdout is 1) shall be the write-end of the pipe and the fd[0] (stdin is 0) shall be the read-end of the pipe. Unlike named pipe(like FIFO - a pipe with name in File system), the anonymous pipes can be used only between related processes like parent-child. So, fork shall be done to duplicate these 2 parent file descriptors in child, thereby parent shares the pipe with child so that the child shall write in write-end and parent shall read from read-end of pipe or Parent shall write into write-end and child shall read from read-end of pipe. Care should be taken to ensure to close the unused read(fd[0]) file descriptor / unused write(fd[1]) file descriptor by the parent or child as per the scenario.

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

popen() : popen enables you to invoke another program as a new process and thereby transmit data to it or receive data from it. In case of popen, note that the direction of data flow is based on the 2nd argument. We need not manually create a child process as popen automatically forks for creating a child process, starts a shell and executes the command argument passed via popen. It also establishes appropriate read or write stream between parent and child automatically based on the type argument.

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

Thus, popen() simplifies things, as it avoids the need to manually call/invoke pipe,fork,exec and simplifies establishment of appropriate streams between parent / child automatically as per argument type. However, the other side of popen is that, it should be noted that every invocation of the popen() shall result in creation of extra process - that is, the shell is invoked every time apart from the program that is being invoked which in-turn leads to high resource consumption.

这篇关于popen2() 在 c 中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆