2012-11-30 173 views
0

我写这将运行Linux命令,像一个C程序:用在for循环fork()的使用来运行2管execlp()创建子DUP

$猫/ etc/passwd文件| cut -f1 -d:|分类

在等待孩子完成时,只有一个孩子终止成功。该代码显示挂起“排序运行”

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <limits.h> 

int main() 
{ 
    int i,fd1[2],fd2[2],status,listpid[3]; 
    pid_t child; 
    pipe(fd1); 
    pipe(fd2); 

    for(i=0; i< 3; i++) 
    { 
    printf("\ncreating child\n"); 
    if((child = fork()) == -1) 
    { 
     perror("fork"); 
     exit(EXIT_FAILURE); 

    } 
    else if(child == 0) 
    { 
     if(i == 0) 
     { 
    close(1); dup(fd1[1]); 
    close(fd1[0]); 
    close(fd1[1]); 
    printf("\nrunning cat /etc/passwd\n"); 
    fflush(stdout); 
    execlp("cat","cat","/etc/passwd", (char *)NULL); 
    exit(EXIT_SUCCESS); 

     } 
     else if(i == 1) 
     { 
    close(0); dup(fd1[0]); 
    close(fd1[1]); 
    close(fd1[0]); 
    close(1); dup(fd2[1]); 
    close(fd2[1]); 
    close(fd2[0]); 
    printf("\nrunning cut -f1 -d:\n"); 
    fflush(stdout); 
    execlp("cut","cut","-f1","-d:", (char *)NULL); 
    exit(EXIT_SUCCESS); 

     } 
     else if(i == 2) 
     { 
    close(0); dup(fd2[0]); 
    close(fd2[1]); 
    close(fd2[0]); 
    close(fd1[0]); 
close(fd1[1]); 
    printf("\nrunning sort\n"); 
    fflush(stdout); 
    execlp("sort","sort", (char *)NULL); 
    exit(EXIT_SUCCESS); 

     } 

    } 
    else 
    { 
     listpid[i]=child; 
    } 

    } 

    close(fd1[0]); 
    close(fd1[1]); 
    close(fd2[0]); 
    close(fd2[1]); 

    for(i = 0; i < 2; i++) 
    { 
    waitpid(listpid[i], &status, 0); 

    if(WIFEXITED(status)) 
    { 
     printf("\n[%d] TERMINATED (Status: %d)\n",listpid[i], WEXITSTATUS(status)); 

    } 

    } 
    exit(EXIT_SUCCESS); 

} 

回答

0

您需要关闭管道fd1儿童2,否则孩子将1挂等待更多可能的输入。

作为另一个问题,您的waitpid循环应具有循环条件i < 3而不是i < 2

1

它“挂”,就是因为sort正在等待更多的输入。在输入管道关闭之前它不会输出任何东西。有可能是你的管道有问题(你应该检查返回值从pipedup),但我什么都看不到。

我的猜测是,cut尚未退出。同样,最可能的原因是,它的输入管道未关闭。那么,它在哪里开放?

因为没有理由认为不会退出这不会是在cat进程中打开。

它不会在父进程中打开,因为您已仔细关闭了所有描述符。

它将不会在cut进程中打开,因为您关闭了fd1的写入结束。

这就让sort处理本身:仍然有fd1的描述符打开!

所以,sort挂起,因为它在等待cut完成,并cut挂起,因为它在等待sort,即使那种永远不会写什么FD1。

您应该关闭第三个孩子中的fd1,或者您应该安排每个管道只存在于需要它们的孩子中。

无论如何,这是我的理论。