【发布时间】:2014-01-24 07:10:19
【问题描述】:
我不知道为什么我可以通过一个 fork 成功管道,但不能通过 2。第一个示例给出的预期输出等同于“ps -A | grep bash”,第二个示例应该给出“ps -A | grep bash | wc -l" 这只是第一个输出产生的行数。相反,它没有输出,只是挂起。
这行得通:
#include <iostream>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char* argv[])
{
int p1[2], p2[2];
pipe(p1); pipe(p2);
pid_t pID;
pID = fork();
if (pID == 0)
{
close(p2[0]);
dup2(p2[1], 1);
close(p2[1]);
execlp("ps", "ps", "-A", 0); // print all processes
}
else
{
wait(pID);
close(p2[1]);
dup2(p2[0],0);
close(p2[0]);
execlp("grep", "grep", "bash", NULL); // search for bash (in process list)
}
}
但这不是:
#include <iostream>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char* argv[])
{
int p1[2], p2[2];
pipe(p1); pipe(p2);
pid_t pID;
pID = fork();
if (pID == 0)
{
pID = fork();
if (pID == 0)
{
close(p2[0]);
dup2(p2[1], 1);
execlp("ps", "ps", "-A", 0); // print all processes
}
else
{
wait(pID);
close(p2[1]);
dup2(p2[0],0);
close(p1[0]);
dup2(p1[1], 1);
execlp("grep", "grep", "bash", 0); // search for bash (in process list)
}
}
else
{
wait(pID);
close(p1[1]);
dup2(p1[0],0);
execlp("wc", "wc", "-l", 0); // count lines
}
}
【问题讨论】:
-
有很多相关的问题。简短的回答是您没有关闭足够多的文件描述符。在对
dup2()进行适当调用后,三个进程中的每一个都应关闭 4 个管道描述符。如果你不这样做,那么grep的标准输入有两个进程仍然可以写入它(grep和wc),所以grep永远不会得到 EOF,所以wc永远不会得到 EOF ,所以一切都卡住了。 -
不要在level0启动所有管道,在level1定义p1;和p2在level2,问题解决了。此外,不要混合 C 和 C++ 的东西......
-
@moeCake,谢谢,成功了。
-
Jonathan 的解决方案也有效。
-
如果不是为了学习,可以使用popen()。