[英]Unix C pipe Question
我试图了解管道的用法。
父进程将进行管道传输,如果是父进程,子进程将继承管道。 那么现在我们与子进程有直接联系,他们可以沟通吗?
当我们开始关闭管道并重定向管道时,我迷路了。 有没有人对关闭管道和重定向管道有一个很好的解释?
先感谢您。
这是交易。
这是它的样子:
P1=[WR FD]===========[RD FD]=[STDIN]=P2
P1=[RD FD]===========[WR FD]=[STDOUT]=P2
P1 and P2 are processes. And "===" depict the pipes.
您的问题专门针对关闭和重定向。 当你执行我之前提到的开关时,它就会发挥作用。 假设您已通过使用pipe()系统调用获取了管道。
int fd[2];
pipe(fd);
现在您创建一个子进程,并在该进程中执行切换,如下所示:
if (!fork()) // 0 return value indicates that you are in the child process
{
dup2(fd[0], 0); // dup2 first closes 0 in the child process, then duplicates
// fd[0] as 0; keep in mind that 0 is stdin and fd[0] is the
// read end of the pipe
exec(something); // start the new process, which when it reads stdin, will be
// reading the pipe instead
}
见管道 。
简单的例子
ls -l | less
在此示例中,ls是Unix目录列表器,less是具有搜索功能的交互式文本寻呼机。 管道允许用户向上和向下滚动可能不适合屏幕的目录列表。
以编程方式创建管道
可以在程序控制下创建管道。 Unix
pipe()
系统调用要求操作系统构造一个新的匿名管道对象。 这导致进程中有两个新的打开文件描述符:管道的只读端和只写端。 管道端部看起来是正常的匿名文件描述符,除了它们没有能力搜索。为了避免死锁并利用并行性,具有一个或多个新管道的Unix进程通常会调用
fork()
来创建新进程。 然后,每个过程将关闭在生成或使用任何数据之前不会使用的管道的末端。
您使用dup
系列调用将新文件描述符更改为前三个系统调用之一。
int new_stdout = open("filename", O_WRONLY);
/* ... error check ... */
if (!fork()) {
/* in child */
dup2(new_stdout, 1);
execve("program", argv, envp);
这使得“filename”将其标准写入“filename”。
子进程继承父进程的开放描述符。 默认的是stdin,stdout,stderr。 他们没有为孩子提供直接与父母沟通的方法,因为他们实际上是去了控制台。 因此,通常关闭或重定向这些,这样就不会污染父控制台的I / O.
但是如果你打开了一对管道,你可以使用它们继承的描述符来在两个进程之间进行通信。 每个方向使用一个描述符。
我们经常使用烟斗。 正如Amardeep所说,子进程继承了父进程的描述符,包括管道。
以下是2个命令的示例。 我不确定我的n命令算法:-)
void do__pipe(char** cmd1, char** cmd2)
{
int fd[2]; /* fd[0] for reading fd[1] for writting */
if (pipe(fd) == -1)
{
perror("pipe");
}
switch (fork())
{
case -1:
perror("fork"); exit (1);
case 0:
close (fd[0]);
dup2 (fd[1], STDOUT_FILENO);
close (fd[1]);
execvp (cmd1[0], cmd1);
exit (1);
}
dup2(STDIN_FILENO, STDIN_FILENO);
switch (fork())
{
case -1:
perror("fork (2)"); exit (1);
case 0:
close (fd[1]);
dup2 (fd[0], STDIN_FILENO);
close (fd[0]);
execvp (cmd2[0], cmd2);
exit (1);
}u
wait((int*)NULL);
}
这个代码取自我必须为我的学习写的一个小shell,所以char ** cmd1就像[“cat”,“/ etc / passwd”],而cmd2可能是[“wc”,“ - l “]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.