参考资料:

http://www.tldp.org/LDP/lpg/node11.html

http://blog.csdn.net/yeyuangen/article/details/6852682

http://blog.sina.com.cn/s/blog_65c5c5990100mx6d.html

管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。

下面是一个最简单的匿名管道的例子。

子进程中,先关闭管道的读出端,然后在管道的写端写入数据

在父进程中,先关闭管道的写入端,然后在管道的读出端读出数据。

int pipe( int fd[2] ); 
NOTES: fd[0] is set up for reading, fd[1] is set up for writing
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h> int main(void)
{
int fd[], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[]; pipe(fd); if ((childpid = fork()) == -)
{
perror("fork");
exit();
} if (childpid == )
{
/* Child process closes up input side of pipe */
close( fd[] ); /* Send "string" through the output side of pipe */
write(fd[], string, (strlen(string)+));
exit();
}
else
{
/* Parent process closes up output side of pipe */
close( fd[] ); /* Read in a string from the pipe */
nbytes = read(fd[], readbuffer, sizeof(readbuffer));
if (nbytes != -)
{
printf("Received string: %s", readbuffer);
} } return();
}

下面将dup跟管道结合其来使用。

在子进程中调用  dup2(fd[1], STDOUT_FILENO); 则printf("hello world\n");的数据就会写入到fd[1]中

在父进程中调用 dup2(fd[0], STDIN_FILENO); 则fgets(readbuffer, sizeof(readbuffer), stdin);会把fd[0]的数据读取出来。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h> int main(void)
{
int fd[], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[]; pipe(fd); if ((childpid = fork()) == -)
{
perror("fork");
exit();
} if (childpid == )
{
/* Child process closes up input side of pipe */
close( fd[] ); /* Send "string" through the output side of pipe */
dup2(fd[], STDOUT_FILENO);
//write(fd[1], string, (strlen(string)+1));
printf("hello world\n");
fflush(stdout);
exit();
}
else
{
/* Parent process closes up output side of pipe */
close( fd[] ); /* Read in a string from the pipe */
dup2(fd[], STDIN_FILENO);
//nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
fgets(readbuffer, sizeof(readbuffer), stdin);
if (nbytes != -)
{
printf("from the stdin,Received string: %s", readbuffer);
} } return();
}

Often, the descriptors in the child are duplicated onto standard input or output. The child can then exec() another program, which inherits the standard streams. Let's look at the dup2() system call:

我们的子进程把它的输出重定向的管道的写端,然后,父进程将它的输入重定向到管道的读端

子进程关闭 管道读端  close( fd[0] );  调用  dup2(fd[1], STDOUT_FILENO);  将管道的写端重定向到标准输出

父进程关闭 管道写端 close( fd[1] );   调用  dup2(fd[0], STDIN_FILENO);    将管道的读端重定向到标准输入

The child can then exec() another program, which inherits the standard streams.

工作流程:

子进程调用  execlp( "ls", "ls", "-1", NULL );  ----> 标准输出----->管道的写端------->

管道的读端(父进程)------->标准输入---->execlp( "wc", "wc", "-l", NULL );

我们看到的结果是  ls -1|wc -l 的结果

管道命令的使用  :

第一条命令 | 第二条命令

将第一条命令的结果作为第二条命令的参数来使用

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h> int main(void)
{
int fd[], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[]; pipe(fd); if ((childpid = fork()) == -)
{
perror("fork");
exit();
} if (childpid == )
{
/* Child process closes up input side of pipe */
close( fd[] ); /* Send "string" through the output side of pipe */
dup2(fd[], STDOUT_FILENO);
execlp( "ls", "ls", "-1", NULL ); exit();
}
else
{
/* Parent process closes up output side of pipe */
close( fd[] ); /* Read in a string from the pipe */
dup2(fd[], STDIN_FILENO);
execlp( "wc", "wc", "-l", NULL ); } return();
}

无名管道跟dup,dup的使用的更多相关文章

  1. linux进程间通信之一:无名管道

    无名管道是linux中管道通信的一种原始方法,有以下特征: 1.单工通信模式,具有固定的读端和写端: 2.管道可以看成是一种特殊的文件,对于它的读写可以使用普通的read(),write()等文件IO ...

  2. Linux 进程通信(无名管道)

    无名管道 无名管道是半双工的,就是对于一个管道来讲,只能读,或者写. 无名管道只能在相关的,有共同祖先的进程间使用(即一般用户父子进程). 一个fork或者execve调用创建的子进程继承了父进程的文 ...

  3. linux进程间通信--无名管道

    管道 只能用于具有亲缘关系的进程之间通信是一个半双工的通信模式, 具有固定的写读端和写端,管道可以看成一种特殊的文件,对它可以使用普通的read.write等操作 管道的创建: #include &l ...

  4. Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)

    一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o te ...

  5. linux之无名管道

    1.查看命令: man 2 pipe 2.头文件:#include <unistd.h> 3.函数原型: int pipe(int pipefd[2]); a.pipefd[2] :无名管 ...

  6. UNIX环境高级编程——无名管道和有名管道

    一.进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2 ...

  7. 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)

     进程间通信IPC之--无名管道(pipe)和有名管道(fifo) 2012-01-17 22:41:20 分类: C/C++ 每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中 ...

  8. linux无名管道

    特点 无名管道是半双工的,也就是说,一个管道要么只能读,要么只能写 只能在有共同祖先的进程间使用(父子进程.兄弟进程.子孙进程等) fork或者execve调用创建的子进程,继承了父进程的文件描述符 ...

  9. Linux 进程间通信 无名管道(pipe)

    无名管道: 1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开) 2)半双工的通信模式,具有固 ...

随机推荐

  1. 09: python基础补充

    1.1 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数 ...

  2. 在win和android上同时进行OpenCV程序设计

    基于qt进行Android图像处理项目设计的时候,初期可以首先在windows上进行调试,等到比较成熟后将代码转换到adnroid上. 这里仅以widget为例,如果使用qtquick是一样的.具体以 ...

  3. 20145317 网络对抗技术 逆向与Bof基础

    20145317 网络对抗技术 逆向与Bof基础 实践要求 1. 掌握NOP,JNE,JE,JMP,CMP汇编指令的机器码 2. 掌握反汇编与十六进制编程器 3. 能正确修改机器指令改变程序执行流程 ...

  4. 在ubuntu下随意编译安装需要的python版本

    一.环境 ubuntu14.04 二.准备 2.1更新软件库 sudo apt-get update 2.2安装编译器及相应工具 2.3安装相应的开发库 sudo apt-get install zl ...

  5. TeeChart设置图表的标题

    TeeChart的图表的标题设置方法 tChart1.Header.Text = "图表"; tChart1.Header.Lines = new string[] { " ...

  6. [BZOJ3613][Heoi2014]南园满地堆轻絮 二分答案

    Description 小 Z 是 ZRP(Zombies’ Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近 他研究起了诗词音律的问题.   在过去,诗词是需要编成曲子唱 ...

  7. LA 4329 乒乓比赛

    https://vjudge.net/problem/UVALive-4329 题意: 一条大街上住着n个兵乓球爱好者,经常组织比赛切磋技术.每个人都有一个不同的技能值ai.每场比赛需要3个人:两名选 ...

  8. POJ 1011 Sticks(dfs+剪枝)

    http://poj.org/problem?id=1011 题意:若干个相同长度的棍子被剪成若干长度的小棍,求每根棍子原来的可能最小长度. 思路:很经典的搜索题. 我一开始各种超时,这题需要很多剪枝 ...

  9. Python subprocess模块学习总结--转载

    一.subprocess以及常用的封装函数运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python ...

  10. win7(64)未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序

    注:本文为个人学习摘录,原文地址:http://blog.163.com/rihui_7/blog/static/2122851432013627103337825/ 1.以前在win7 64位系统上 ...