2014-04-01 106 views
0

我有我的大学的作业,其中我必须有一个主进程和3个子进程。我必须从用户处读取主进程中的表达式,然后通过标准输入重定向的p1进程中的匿名管道传递它。然后我必须修改它,并用另一个管道将它传递给p2。然后,p3和另一个管道发生同样的事情。最后,我必须使用另一个管道将最终表达式从p3返回到主进程。当我通过调用fork来创建主进程中的p1,p2,p3进程时,我使用execlp来运行这些进程中的每一个的代码。用execlp在c中匿名管道

我到现在为止所做的工作(除了每个进程的逻辑非常复杂外),是将用户的表达从主进程发送到p1进程。在主进程中的p1的代码中,我重定向到p1的输入到第一个管道的读取结束,并且我成功从主进程读取表达式。

我的问题是与其他进程。我真的被困在如何正确地重定向每个管道的输入和输出以与所有进程进行通信。我真的很感谢这里的任何帮助。 预先感谢您。

回答

0

在这个例子中,你可以看到execlp()函数和fork()的函数:

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

main() 
{ 
    pid_t pid; 
    char *pathvar; 
    char newpath[1000]; 

    pathvar = getenv("PATH"); 
    strcpy(newpath, pathvar); 
    strcat(newpath, ":u/userid/bin"); 
    setenv("PATH", newpath); 

    if ((pid = fork()) == -1) 
     perror("fork error"); 
    else if (pid == 0) { 
     execlp("newShell", "newShell", NULL); 
     printf("Return not expected. Must be an execlp error.n"); 
    } 
} 

在这里你可以看到如何使两种工艺之间的管道:

/* 
“ls -R | grep <pat>” where <pat> is a pattern 
*/ 

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

int main(int argc, char *argv []) 
{ 
    int pipe1[2]; 
    int pid1; 
    int pid2; 
    char stringa[100]; 

    pipe(pipe1); // creo la pipe 

    if((pid1=fork())==0) 
    { 
     close(pipe1[0]); 
     dup2(pipe1[1],1); 
     close(pipe1[1]); 
     execlp("ls","ls","-R",NULL); 
    } 

    if((pid2=fork())==0) 
    { 
     close(pipe1[1]); 
     dup2(pipe1[0],0); 
     close(pipe1[0]); 
     execlp("grep","grep",argv[1],NULL); 
    } 

    close(pipe1[0]); 
    close(pipe1[1]); 
    waitpid(pid1,NULL,0); 
    waitpid(pid2,NULL,0); 
    exit(0); 

} 
+0

谢谢你的回答。第二个例子更接近我所需要的。这是我的问题。为什么在第二个过程中你不关闭fd的读取结束?为什么在父进程中关闭管道的读写? – zarzonis

+0

匿名管道是一个通信通道,它将两个进程与一个共同的祖先进行连接。 每个管道都有进出。每个访问都有一个文件描述符。 当进程使用管道的一侧时,必须用close()关闭文件描述符。 – elviuz

+0

我必须关闭我使用的管道或者我没有使用的那一侧? – zarzonis

0

从你的描述我想你想链分叉。例如。而不是让主叉三次创建p1,p2和p3,而是让主叉一次创建p1,然后让p1叉一次创建p2,同时分叉一次创建p3。

+0

谢谢为你的答案。我对流程很陌生,我需要更多的帮助。我该如何做你的建议?请记住,我必须在3个子进程中的每一个中使用execlp来执行每个进程的代码。实际上我现在所做的就是调用fork 3次并保存创建的进程的id。然后在每个进程的代码中,在我调用execlp之前,我重定向输入和输出,并关闭所有不使用的管道。但我不确定我是否关闭并重定向了一切。 – zarzonis