无名管道跟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)半双工的通信模式,具有固 ...
随机推荐
- 20145127 《Java程序设计》第五次实验报告
实验简述: 在本周,我们进行了Java的第五次试验,本次实验的主要内容是结对编程.本次实验的大体过程是: 1.先进行Java的客户端与服务端的代码编写.结对是两个人,一人负责客户端,一人负责服务端. ...
- 20165310_JavaExp1
20165310_JavaExp1_Java开发环境的熟悉 一.Exp1 Exp1_1 实验目的与要求: 使用JDK编译.运行简单的Java程序: 使用Vim进行Java源代码编译: 利用Git上传代 ...
- 小工具:使用Python自动生成MD风格链接
很久之前我在Github上搞了一个LeetCode的仓库,但一直没怎么维护.最近发现自己刷了不少LC的题目了,想搬运到这个仓库上. 玩Github最重要的当然是写README了,MD的逼格决定了项目牛 ...
- React 回忆录(一)为什么使用 React?
Hi 各位,欢迎来到 React 回忆录!
- Python3基础 str while+iter+next 字符串的遍历
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 用Python为iOS和Android写跨平台的应用
首先保证安装了最新的python(当前安装的是python3.6) 一.安装Kivy :python -m pip install --upgrade pip wheel setuptools pyt ...
- POJ 1704 Georgia and Bob(阶梯博弈)题解
题意:有一个一维棋盘,有格子标号1,2,3,......有n个棋子放在一些格子上,两人博弈,只能将棋子向左移,不能和其他棋子重叠,也不能跨越其他棋子,不能超越边界,不能走的人输 思路:可以用阶梯博弈来 ...
- MySQL 5.7.18 解压版安装
原文链接:https://my.oschina.net/u/3474266/blog/895696 我在安装免安装版的5.7.18的时候出现了问题,正好找到这个,十分感激 今天下载安装了MySQL C ...
- java数字格式化
[转载] Java 提供 DecimalFormat 类,帮你用最快的速度将数字格式化为你需要的样子.下面是一个例子: importjava.text.DecimalFormat; publiccla ...
- HDU 5834 Magic boy Bi Luo with his excited tree(树形dp)
http://acm.hdu.edu.cn/showproblem.php?pid=5834 题意: 一棵树上每个节点有一个价值$Vi$,每个节点只能获得一次,每走一次一条边要花费$Ci$,问从各个节 ...