无名管道跟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[2], nbytes;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    readbuffer[80];

    pipe(fd);

    if ((childpid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    if (childpid == 0)
    {
        /* Child process closes up input side of pipe */
        close( fd[0] );

        /* Send "string" through the output side of pipe */
        write(fd[1], string, (strlen(string)+1));
        exit(0);
    }
    else
    {
        /* Parent process closes up output side of pipe */
        close( fd[1] );

        /* Read in a string from the pipe */
        nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
        if (nbytes != -1)
        {
            printf("Received string: %s", readbuffer);
        }

    }

        return(0);
}

下面将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[2], nbytes;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    readbuffer[80];

    pipe(fd);

    if ((childpid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    if (childpid == 0)
    {
        /* Child process closes up input side of pipe */
        close( fd[0] );

        /* Send "string" through the output side of pipe */
        dup2(fd[1], STDOUT_FILENO);
        //write(fd[1], string, (strlen(string)+1));
        printf("hello world\n");
        fflush(stdout);
        exit(0);
    }
    else
    {
        /* Parent process closes up output side of pipe */
        close( fd[1] );

        /* Read in a string from the pipe */
        dup2(fd[0], STDIN_FILENO);
        //nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
        fgets(readbuffer, sizeof(readbuffer), stdin);
        if (nbytes != -1)
        {
            printf("from the stdin,Received string: %s", readbuffer);
        }

    }

        return(0);
}

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[2], nbytes;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    readbuffer[80];

    pipe(fd);

    if ((childpid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    if (childpid == 0)
    {
        /* Child process closes up input side of pipe */
        close( fd[0] );

        /* Send "string" through the output side of pipe */
        dup2(fd[1], STDOUT_FILENO);
        execlp( "ls", "ls", "-1", NULL );

        exit(0);
    }
    else
    {
        /* Parent process closes up output side of pipe */
        close( fd[1] );

        /* Read in a string from the pipe */
        dup2(fd[0], STDIN_FILENO);
        execlp( "wc", "wc", "-l", NULL );

    }

    return(0);
}
时间: 2024-10-12 19:08:28

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

进程之间通信之有名管道、无名管道(pipe),笔记

             进程之间的通信作用1.数据传输   :一个进程需要将他的数据传到其他进程2.资源共享3.进程通知事件4.进程控制 :有些进程完全控制另一个进程的执行,如调试状态啊我们需要完全控制他的每一步操作: 通信发展历史Linux进程间的通信IPC由以下几个部分发展而来:1.UNIX进程之间的通信2.基于system v进程间的通信3.POSIX进程之间的通信(portable operating system interface) 现在Linux使用的进程间的通信方式包括:1.管

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

一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o test.i 编译:   不同平台使用汇编语言不同,汇编将高级语言编译成汇编语言: gcc -S test.c -o test.s 汇编:   将汇编语言翻译成二进制代码: gcc -c test.c -o test.o 链接:   包含各函数库的入口,得到可执行文件: gcc -o test test.c (2

13.无名管道通讯编程

? 1.进程间的通信: Linux作为典型的多进程操作系统,进程与进程之间肯定需要信息交流,这就需要进程通信. 2.进程通信的目的: ????1.数据传输:一个进程需要将数据发送给另一个进程. ????2.资源共享:多个进程之间共享同样的资源. ????3.通知事件:一个进程需要向另一个/组进程发送信息,通知他们发生了某些事情. ????4.进程控制:有些进程希望完全控制另一个进程的执行,例如Debug进程.此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道他的状态改变. ? 3.通讯

无名管道通讯编程

创建无名管道用于父子间进程通信. 1.无名管道概念:无名管道又称pipe,是Linux所支持的IPC方式的一种,它具有以下特点: 1)只能用于具有血缘关系的进程之间. 2)属于半双工的通信模式,具有固定的读端和写端 3)是一种特殊的文件,存在于内存中,可通过read.write对其操作. 2.无名管道的用法 因为pipe存在于内存中,所以无法像操作普通文件那样通过指定路径来打开文件.通常的做法是在父进程中创建管道,再创建子进程.由于子进程继承了父进程打开的文件描述符,所以父子进程就可以通过创建的

管道通信之无名管道---pipe()

pipe()函数在子进程产生之前就应该存在. 父子进程之间只进行一次传递 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:onepipe.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #inclu

进程通信-无名管道

无名管道:主要是针对进程通信的(自己感觉它有很大的局限性) 特点:它不是一个文件系统,不能按名访问,这也是它和有名管道之间最大的区别.无名管道只是一个系统内存里面的东西. 半双工模式,数据只能流向一个方向(老师给我们举得例子就是水厂的水到居民用水,不可能倒着流对吧). 进程之间通信,但是只能是有亲缘关系的进程才能进行通信?比如父子进程:因为在父子进程中,子进程拷贝父进程的数据段,这让这两个进程在通信的时候就有了相连的关系. 下面我们来看一下:无名管道的创建,写入,读取,关闭(我用的的是Liunx

[国嵌攻略][080][无名管道通讯]

通讯目的 1.数据传输 一个进程需要将数据发送给另外一个进程. 2.资源共享 多个进程之间共享同样的资源. 3.通知事件 一个进程需要向另外一个/组进程发送消息,通知它们发生了某事件. 4.进程控制 有些进程希望完全控制另外一个进程的执行,此时控制进程希望能够拦截另外一个进程的所有操作,并能够及时知道它的状态改变. 通信方式 1.无名管道(pipe):数据传输 2.有名管道(fifo):数据传输 3.信号(signal):通知事件 4.消息队列 5.内存共享 6.信号量:资源共享 7.套接字(s

第11课-无名管道通讯

1.进程间通讯的目的(1)数据传输(2)资源共享(3)通知事件(4)进程控制2.通讯发展(1)UNIX进程间通讯(2)基于System V进程间通讯(3)POSIX进程间通讯3.POSIX标准4.进程间通讯的主要方式(1)无名管道(2)有名管道(3)信号(4)消息队列(5)共享内存(6)信号量(7)套接字5.管道通信(1)一个进程在管道尾部写入数据,另一个进程管道头部读取数据(2)无名管道:只能用于父进程子进程之间的通讯(3)有名管道:可以用于任意两个进程间的通讯6.管道特点:(1)管道通讯是单

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

无名管道是linux中管道通信的一种原始方法,有以下特征: 1.单工通信模式,具有固定的读端和写端: 2.管道可以看成是一种特殊的文件,对于它的读写可以使用普通的read(),write()等文件IO操作函数接口,但是它不属于任何文件系统,并且只存在与内存中: 3.只能用于具有亲缘关系的进程之间的通信: 4.通常使用时,首先创建一个管道,然后调用fork函数创建一个子进程,该子进程会继承父进程所创建的管道: 5.只有在管道的读端存在时,向管道写入数据才有意义,否则向管道写入的数据的进程将收到内核