我试图在我的程序中使用pipe,fork和dup.i执行md5sume命令,找到成功运行的和代码,但我无法理解某些代码行。这是我的代码:
event.target.tagName
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;
}
我不懂popen功能。这条线究竟做了什么?
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;
}
管道如何相互通信?
答案 0 :(得分:1)
我不懂popen功能。
管道如何相互通信?
pipe():管道是单向的,内核中是字节流缓冲区。由于它是字节流类型,因此写入器可以以任意数量的字节写入,读取器可以读出任意数量的字节。但是,请注意顺序读取是可能的,但是搜索(如lseek)是不可能的。由于管道是单向的,因此写入管道的数据应在内核中缓冲,直到从管道的读取端读取。此外,如果管道已满,则写入块。
让我们考虑fd是一个包含2个文件描述符的整数数组(int fd [2]),然后管道(fd)系统调用将创建一个管道并返回一对文件描述符,使得fd [1](stdout)是1)应该是管道的写端,而fd [0](stdin为0)应该是管道的读端。与命名管道(如FIFO - 文件系统中具有名称的管道)不同,匿名管道只能在父子等相关进程之间使用。因此,fork应该在子节点中复制这两个父文件描述符,从而父节点与子节点共享管道,以便子节点写入写入端,父节点应从管道的读取端读取,或者父节点应写入写入 - 结束和孩子应从管道的读取端读取。应注意确保按照方案关闭父节点或子节点的未使用的读取(fd [0])文件描述符/未使用的写入(fd [1])文件描述符。
popen(): popen使您可以将另一个程序作为新进程调用,从而向其传输数据或从中接收数据。如果是popen,请注意数据流的方向基于第二个参数。我们不需要手动创建子进程,因为popen会自动创建子进程,启动shell并执行通过popen传递的命令参数。它还根据类型参数自动在父级和子级之间建立适当的读取或写入流。
因此,popen()简化了事情,因为它避免了手动调用/调用管道,fork,exec的需要,并且根据参数类型自动简化父/子之间的适当流的建立。但是,popen的另一面是,应该注意的是,popen()的每次调用都会导致创建额外的进程 - 也就是说,每次调用shell时,都会调用shell,而不是正在调用的程序。转向导致高资源消耗。