无名管道跟dup,dup的使用
参考资料:
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的使用的更多相关文章
- linux进程间通信之一:无名管道
无名管道是linux中管道通信的一种原始方法,有以下特征: 1.单工通信模式,具有固定的读端和写端: 2.管道可以看成是一种特殊的文件,对于它的读写可以使用普通的read(),write()等文件IO ...
- Linux 进程通信(无名管道)
无名管道 无名管道是半双工的,就是对于一个管道来讲,只能读,或者写. 无名管道只能在相关的,有共同祖先的进程间使用(即一般用户父子进程). 一个fork或者execve调用创建的子进程继承了父进程的文 ...
- linux进程间通信--无名管道
管道 只能用于具有亲缘关系的进程之间通信是一个半双工的通信模式, 具有固定的写读端和写端,管道可以看成一种特殊的文件,对它可以使用普通的read.write等操作 管道的创建: #include &l ...
- Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)
一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o te ...
- linux之无名管道
1.查看命令: man 2 pipe 2.头文件:#include <unistd.h> 3.函数原型: int pipe(int pipefd[2]); a.pipefd[2] :无名管 ...
- UNIX环境高级编程——无名管道和有名管道
一.进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2 ...
- 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)
进程间通信IPC之--无名管道(pipe)和有名管道(fifo) 2012-01-17 22:41:20 分类: C/C++ 每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中 ...
- linux无名管道
特点 无名管道是半双工的,也就是说,一个管道要么只能读,要么只能写 只能在有共同祖先的进程间使用(父子进程.兄弟进程.子孙进程等) fork或者execve调用创建的子进程,继承了父进程的文件描述符 ...
- Linux 进程间通信 无名管道(pipe)
无名管道: 1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开) 2)半双工的通信模式,具有固 ...
随机推荐
- dba和运维专家们说有丰富的大型分布式系统架构设计经验纯属扯淡
如果,一开始就从事dba和运维的专家们说他们有丰富的大型分布式系统架构设计经验,那纯属扯淡.除非,他们从是从开发专家或者架构师转型而来,那么他们才有资格说自己有丰富的大型分布式系统架构设计经验. 运维 ...
- 05: jQuery
目录: jQuery参考网站 W3school 1.1 JQuery作用 1.2 jQuery与DOM比较 与 相互转换 1.3 jQuery选择器 1.4 jQuery筛选与过滤 1.5 jQuer ...
- C#调用托管ocx、dll
前篇文章是调用非托管,比较复杂,这里是调用托管,很简单[所以在遇到非托管dll时可以通过二次封装成托管的方式,再通过这边文章来使用] 1.注意这是基于COM的ocx或者dll,所以用regsvr32先 ...
- Python3基础 list str转成list
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- nmap参数思维导图
链接:https://pan.baidu.com/s/1vD0A6olQbVNmCCirpHBm0w 提取码:o994
- 【附7】turbine
一.作用 聚集同一个微服务的相同的commandKey.Threadpool.commandGroupKey数据进行聚合 二.配置 1.集群(cluster)(turbine聚集数据的粒度) turb ...
- 51nod 1103 N的倍数
1103 N的倍数 一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数. 例如:N = 8,数组A包括:2 5 6 3 18 7 11 19,可以选2 6,因为2 + 6 = 8, ...
- BZOJ5170: Fable 树状数组
Description 有这么一则传闻,O(nlogn)的排序发明之前,滋滋国的排序都是采用的冒泡排序.即使是冒泡排序,对当时的国民 来说也太复杂太难以理解,于是滋滋国出现了这样一个职业——排序使,收 ...
- ajax中的contentType使用
本文为博主原创,未经允许不得转载: 最近在修改部分项目功能的时候,遇到一个问题.局部刷新某页面的功能是由ajax实现的,但当我进行局部刷新的时候,页面并没有刷新和响应, 在后台的代码中打了断点也并没有 ...
- maven 插件在线安装
NO.1 在Eclipse中安装Maven插件安装详解 前言 本来是没打算写博客的,作为一个13年毕业的菜鸟,自认为水平太渣写不出什么好文章,但是前些日子看到一篇鼓励性质的文章说,技术人员的成长靠的就 ...