Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1047933
  • 博文数量: 297
  • 博客积分: 11721
  • 博客等级: 上将
  • 技术积分: 3431
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-25 10:21
文章分类

全部博文(297)

文章存档

2016年(9)

2011年(71)

2010年(137)

2009年(80)

分类: C/C++

2009-11-23 22:33:28

11.2.4 连接标准I/O的管道模型

  管道在shell中最常见的应用是连接不同进程的输入输出,比如使A进程的输出变成B进程的输入等。考察shell命令“cat pipe3.c | more”,进程“more”使用了进程“cat pipe3.c”的输出。

  例1. 分别重定向标准输入、标准输出、标准错误输出到文件描述符fd1、fd2和fd3中。

  答:复制文件描述符fd1到文件描述符0中即可重定向标准输入,其它的类似,如以下语句所示:

  dup2(fd1, 0);   /* 复制fd1到文件描述符0中,更改标准输入为fd1 */

  dup2(fd2, 1);   /* 复制fd2到文件描述符1中,更改标准输出为fd2 */

  dup2(fd3, 2);   /* 复制fd3到文件描述符2中,更改标准错误输出为fd3 */

  当执行“dup2(fd1, 0)”后,文件描述符0就对应到了fd1所对应的文件中,而一些标准输出函数,如printf、puts等仍然向描述符0中写入内容,从而达到了重定向的效果。

  模型

  使用管道将父进程标准输入连接到子进程标准输入的方法如下:

  (1) 创建管道,返回无名管道的两个文件描述符fildes[0]和fildes[1]。

  (2) 创建子进程,子进程中继承无名管道文件描述符。

  (3) 父进程关闭管道的输出端,即关闭只读文件描述符fileds[0]。

  (4) 父进程将标准输出(stdout,文件描述符1)重定向为文件描述符fileds[1]。

  (5) 子进程关闭管道的输入端,即关闭只写文件描述符fileds[1]。

  (6) 子进程将标准输入(stdin,文件描述符0)重定向为文件描述符fileds[0]。

  最终创建的管道流如图11-7所示:

标准I/O重定向《精通Unix下C语言编程与项目实践》之七

  图11-7 父子进程标准I/O管道(父进程流向子进程)

  实例

  本处设计一个将父进程标准输出流连接到子进程标准输入流的管道,父进程向stdout输出的“Hello!”直接转移到子进程的stdin,由子进程“gets(buf)”语句所获取。如代码11-6所示:

  代码11-6 父进程的输出连接子进程的输入通信实例(节自/code/chapter11/pipe3.c)

#include
#include
int main()
{
    int fildes[2];
    pid_t pid;
    int i, j;
    char buf[256];
    if (pipe(fildes) < 0 || (pid = fork()) < 0) /* 创建管道和子进程 */
    {
        fprintf(stderr, "error!n");
        return 1;
    }
    if (pid == 0)
    {
    /* ―――――――――――――――――子进程―――――――――――――――――― */
        close(fildes[1]);                  
        dup2(fildes[0], 0);                 /* 重定向stdin到fildes[0]中 */
        close(fildes[0]);
        gets(buf);                          /* 读入输入,其实是读取父进程输出 */
        fprintf(stderr, "child:[%s]n", buf);
        return 2;
    }
    /* ―――――――――――――――――父进程―――――――――――――――――― */
    close(fildes[0]);
    dup2(fildes[1], 1);                     /* 重定向stdout到fildes[1]中 */
    close(fildes[1]);
    puts("Hello!");                         /* 输出,同时增加子进程的输入信息*/
    return 0;                          
}

  编译与运行代码11-6:

# make pipe3
        cc -O -o pipe3 pipe3.c
# ./pipe3
child:[Hello!]

  上例中,父进程的标准输出已经重定向到管道中,故父进程puts未能将结果打印到屏幕上。

  出处:http://zhuyunxiang.blog.51cto.com/653596/134458

阅读(864) | 评论(0) | 转发(0) |
0

上一篇:dup2描述字重定向

下一篇:unix域套接字

给主人留下些什么吧!~~