[英]c - Can't pipe three processes
我一直在嘗試在c: cat / etc / passwd中實現以下命令 cut -f1 -d:| 分類
這是我到目前為止的代碼。 第一個管道正常工作但第二個管道似乎根本不起作用。
我一遍又一遍地檢查代碼,但看不出有什么不對。 任何人都可以提出一個可以解決我的問題的建議嗎?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pipe_A[2];
int pipe_B[2];
pipe(pipe_A);
pipe(pipe_B);
pid_t pid_A, pid_B, pid_C;
if( !(pid_A = fork()) ) {
close(1); /* close normal stdout */
dup(pipe_A[1]); /* make stdout same as pipe_A[1] */
close(pipe_A[0]); /* we don't need this */
execlp("/bin/cat", "cat", "/etc/passwd" , NULL);
}
if( !(pid_B = fork()) ) {
close(0); /* close normal stdin */
dup(pipe_A[0]); /* make stdin same as pipe_A[0] */
close(pipe_A[1]); /* we don't need this */
close(1); /* close normal stdout */
dup(pipe_B[1]); /* make stdout same as pipe_B[1] */
close(pipe_B[0]); /* we don't need this */
execlp("/usr/bin/cut", "cut", "-f1", "-d:", NULL);
}
if( !(pid_C = fork()) ) {
close(0); /* close normal stdin */
dup(pipe_B[0]); /* make stdin same as pipe_B[0] */
close(pipe_B[1]); /* we don't need this */
execlp("/usr/bin/sort", "sort", NULL);
}
return 0;
}
謝謝。
問題是你正在泄漏開放的FD。 請注意,每次調用fork時,所有打開的管道都由子進程繼承,但具有dup'ed FD的管道無法正常工作。
例如, cat
繼承了pipe_B
讀取和寫入pipe_B
。 同樣, sort
繼承了pipe_A
兩個pipe_A
。
正確的方法是沿着(但我建議使用dup2()
代替):
int main(void)
{
int pipe_A[2];
int pipe_B[2];
pid_t pid_A, pid_B, pid_C;
pipe(pipe_A);
if( !(pid_A = fork()) ) {
close(pipe_A[0]); // A-read not needed here
close(1);
dup(pipe_A[1]);
close(pipe_A[1]); //do not pass A-write twice
execlp("/bin/cat", "cat", "/etc/passwd" , NULL);
}
close(pipe_A[1]); // A-write not needed anymore
pipe(pipe_B); //do not create this pipe until needed
if( !(pid_B = fork()) ) {
close(pipe_B[0]); // B-read not needed here
close(0);
dup(pipe_A[0]);
close(pipe_A[0]); //do not pass A-read twice
close(1);
dup(pipe_B[1]);
close(pipe_B[1]); //do not pass B-write twice
execlp("/usr/bin/cut", "cut", "-f1", "-d:", NULL);
}
close(pipe_A[0]); // A-read not needed anymore
close(pipe_B[1]); // B-write not needed anymore
if( !(pid_C = fork()) ) {
close(0);
dup(pipe_B[0]);
close(pipe_B[0]); // do not pass B-read twice
execlp("/usr/bin/sort", "sort", NULL);
}
close(pipe_B[0]); // B-read not needed anymore
return 0;
}
如果你分析我的代碼(如果我寫得正確),假設父進程只有FDs 0,1和2,那么每個execlp()
都會得到3個FD,0,1和2。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.