无名管道跟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)半双工的通信模式,具有固 ...
随机推荐
- codevs 1380 没有上司的舞会 - 树形动态规划
题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个快乐指数.现在有个周年庆宴会 ...
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 1 章 答案
判断对错1.计算机科学是计算机的研究.2.CPU 是计算机的“大脑”.3.辅助存储器也称为 RAM.4.计算机当前正在处理的所有信息都存储在主存储器中.5.语言的语法是它的意思,语义是它的形式.6.函 ...
- CocoaPods的安装及使用
CocoaPods安装使用及配置私有库 http://www.exiatian.com/cocoapods%E5%AE%89%E8%A3%85%E4%BD%BF%E7%94%A8%E5%8F%8A%E ...
- Django框架(四) Django之视图层
视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...
- python 时间元组转可视化时间(自定义)
>>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) '2019-01-04 11:20:25'
- C++宏定义不受命名空间的约束
// xxx.h namespace A { #define xxx() xxxxx } // 在其他文件中,引入xxx.h文件,使用宏定义时,不需要加命名空间 // yyy.cpp #include ...
- Ubuntu14.04 libboost_program_options.so.1.54.0: cannot open shared object file: No such file or directory
macname@ubuntu:~/Desktop$ roslaunch blackrospack: error : cannot open shared object file: No such fi ...
- django模型和字段
一个模型(model)就是一个单独的.确定的数据的信息源,包含了数据的字段和操作方法.通常,每个模型映射为一张数据库中的表. 基本的原则如下: 每个模型在Django中的存在形式为一个Python类 ...
- URAL 1741 Communication Fiend
URAL 1741 思路: dp 状态:dp[i][1]表示到第i个版本为正版的最少流量花费 dp[i][0]表示到第i个版本为盗版的最少流量花费 初始状态:dp[1][0]=dp[0][0]=0 目 ...
- indexedDB入门
localforage localStorage局限性:存储容量限制,仅支持字符串,如果是存对象还需要将使用JSON.stringify和JSON.parse方法互相转换:读取都是同步的.大多数情况o ...