Linux匿名管道

http://blog.chinaunix.net/uid-26000296-id-3408970.html

/*
 * \File
 *   main.c
 * \Descript
 *   father-process reads input file and sends to child-process by anonymous-pipe
 *   client-process transform and write into output file
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

FILE* fp_in = NULL;
FILE* fp_out = NULL;
#define TESTF_IN "test.dat"
#define TESTF_OUT "out.dat"
#define MAX_LINE 512
#define OP_LEN 100

/*
 * \File
 * trans.h
 * \Descript
 *
 */ 

#ifndef __TRANS_H__
#define __TRANS_H__ 

int trans_lower2upper(char* buf_in, char* buf_out, int len);

#endif

/*
 * \Func
 * main
 * \Descript
 *
 */

int main(char argc, char* argv[])
{
  int pidstatus;
  int fdfile_in, fdfile_out;

  int fdpipe_a[2];
  int fdpipe_b[2];
  int pid_trans = -1, pid_write = -1;

  /* Create anonymous-pipe */
  if( (pipe(fdpipe_a) < 0) || (pipe(fdpipe_b) < 0))   //创建两个管道
  {
    printf("open pipe failed.\n");
    exit(1);
  }

  if ( (fp_in = fopen(TESTF_IN, "r")) < 0 )  //打开test.dat文件,用于读
  {
    printf("open input file failed: %s\n", TESTF_IN);
    exit(1);
  }

  if ( (fp_out = fopen(TESTF_OUT, "w")) < 0 )   //新建out.dat文件,用于写
  {
    printf("open input file failed: %s\n", TESTF_OUT);
    exit(1);
  }

  if ( (pid_trans = fork()) && (pid_write = fork()) )    //创建两个子进程,父进程工作内容
  {
    /*
     * PARENT_PROCESS:
     * read data from in-file, write it into anonymos-pipe.
     */

     int s_read = 0, s_write;
     char bufparent[512];    

     while((s_read = fread(bufparent, sizeof(char), OP_LEN ,fp_in) ) ) //读test.dat文件
     {
       printf("***** %d, %s\n", s_read, bufparent);
       if ( (s_write = write(fdpipe_a[1], bufparent, s_read)) < 0 )//向管道写
       {
         printf("write pipe failed.\n");
         exit(1);
       }
       memset(bufparent, 0, 512);
       if( feof(fp_in) != 0 )  //检查文件是否结束
       {
         printf("\n***** read test.dat over ******\n");
         exit(1);
       }
     }
  }
  else if ( pid_trans == 0 )
  {
    /*
     * TRANS_PROCESS:
     * read anonymous-pipe, transcode, write anonymos-pipe.
     */

    char buftrans_in[512], buftrans_out[512];
    int size_read, size_write;
    int ret;

    while(size_read = read(fdpipe_a[0], buftrans_in, OP_LEN)) //读管道
    {
      ret = trans_lower2upper(buftrans_in, buftrans_out, size_read);

      if ( (size_write = write(fdpipe_b[1], buftrans_out, size_read)) < 0 )  //写管道
      {
        printf("trans-process write failed.\n");
        exit(2);
       }
    }
  }
  else if ( pid_write == 0 )
  {
    /*
     * WRITE_PROCESS:
     * read anonymous-pipe, write it into out-file
     */
    int s_read, s_write;
    char bufwrite[512];

    while ( s_read = read(fdpipe_b[0], bufwrite, OP_LEN) )  //读管道
    {
      if( (s_write = fwrite(bufwrite, sizeof(char), s_read, fp_out)) < 0) //写out.dat文件
      {
        printf("..... write error.\n");
        exit(3);
      }
      if(s_read < OP_LEN)
      {
        break;
      }
    }
  }
  else
  {
      printf("fork process failed.\n");
      exit(1);
  }

  waitpid(pid_trans, &pidstatus, 0);
  waitpid(pid_write, &pidstatus, 0);

  fclose(fp_out);
  fclose(fp_in);

  int s_read2 = 0;
  char bufparent2[512];
  if ( (fp_out = fopen(TESTF_OUT, "r")) < 0 )   //新建out.dat文件,用于写
  {
    printf("open input file failed: %s\n", TESTF_OUT);
    exit(1);
  }

  s_read2 = fread(bufparent2, sizeof(char), OP_LEN ,fp_out);
  printf("***** %d, %s\n", s_read2, bufparent2);
  if( feof(fp_out) != 0 )  //检查文件是否结束
       {
         printf("\n***** pirint out.dat over ******\n");
         exit(1);
       }

  fclose(fp_out);

  return 0;

}   

/*
 * \Func
 * trans_lower2upper
 * \Descript
 * Lowercase turn uppercase
 */
int trans_lower2upper(char* buf_in, char* buf_out, int buf_len) //逐个字符转换成大写字母
{
  int len = buf_len;
  char* cp_in = buf_in;
  char* cp_out = buf_out;
  char atom;
  char offset;

  while(len--)
  {
    atom = *(cp_in++);

    if( (atom >= ‘a‘) && (atom <= ‘z‘) )
    {
      offset = atom - ‘a‘;
      atom = ‘A‘ + offset;
    }
    *(cp_out++) = atom;
  }

  return 0;
}

运行结果如下

出现的问题是 打印out.dat文件内容时,打印了[email protected]:$

时间: 2024-07-31 12:26:49

Linux匿名管道的相关文章

你所不知道的linux匿名管道知识

相信很多在linux平台工作的童鞋, 都很熟悉管道符 '|', 通过它, 我们能够很灵活的将几种不同的命令协同起来完成一件任务.就好像下面的命令: 不过这次咱们不来说这些用法, 而是来探讨一些更加有意思的, 那就是 管道两边的数据流"实时性" 和 管道使用的小提示. 其实我们在利用管道的时候, 可能会不经意的去想, 我前一个命令的输出, 是全部处理完再通过管道传给第二个命令, 还是一边处理一边输出呢? 可能在大家是试验中或者工作经验中, 应该是左边的命令全部处理完再一次性交给右边的命令

linux系统编程之管道(一):匿名管道(pipe)

原文地址:http://www.cnblogs.com/mickole/p/3192210.html 一,什么是管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. 数据的读

Linux进程间通信 -- 使用匿名管道

在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什么是管道 如果你使用过Linux的命令,那么对于管道这个名词你一定不会感觉到陌生,因为我们通常通过符号“|"来使用管道,但是管理的真正定义是什么呢?管道是一个进程连接数据流到另一个进程的通道,它通常是用作把一个进程的输出通过管道连接到另一个进程的输入. 举个例子,在shell中输入命令:ls -l

Linux进程通信----匿名管道

Linux进程通信中最为简单的方式是匿名管道 匿名管道的创建需要用到pipe函数,pipe函数参数为一个数组 表示的文件描述字.这个数组有两个文件描述字,第一个是用 于读数据的文件描述符第二个是用于写数据的文件描述符. 不能将用于写的文件描述符进行读操作或者进行读的文件描述 符进写操作,这样都会导致错误. 关于匿名管道的几点说明: 1.匿名管道是半双工的,即一个进程只能读,一个进程只能写    要实现全双工,需要两个匿名管道. 2.只能在父子进程或者兄弟进程进行通信. 3.在读的时候关闭写文件描

Linux - 进程间通信 - 匿名管道

一.概念:进程间通信( IPC,InterProcess Communication) 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进城之间要交换数据必须通过内核, 在内核中 开辟一块缓冲区进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内接提供的这种机制成为进程间 通信(IPC,InterProcess Communication). 二.管道 管道分为匿名管道和命名管道,这里我们只讲匿名管道,命名管道的实现将在下一篇文章中分享.

Linux进程间通信-匿名管道

前面我们讲了进程间通信的一种方式,共享内存.下面看一看另一种机制,匿名管道.1.什么是管道管道是一个进程的数据流到另一个进程的通道,即一个进程的数据输出作为另一个进程的数据输入,管道起到了桥梁的作用.比如,在shell中输入命令:ls -l|grep string,ls和grep是两个进程,"|"符号表示管道,意思是执行ls -l进程,并将输出结果result_1,作为grep string进程的输入result_0,grep进程将result_0中存在字符串string的信息打印到屏

进程间通信IPC—匿名管道(pipe)和命名管道(fifo)

管道内部如何实现-大小,组织方式,环形队列? 一.进程间通信有多种方式,本文主要讲解对管道的理解.管道分为匿名管道和命名管道. (1)管道( pipe ):又称匿名管道.是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系. (2)命名管道 (named pipe或FIFO) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信. 二.管道 1. 管道的特点: (1)管道是半双工的,数据只能向一个方向流动:双方通信时,需要

linux学习——管道

这篇文章简单介绍一下操作系统中的管道,并主要解决以下两个问题: 1.管道的内部实现 2.管道的容量? 管道是操作系统中,不同进程之间进行通信的方式. 根据通信的进程之间的关系,管道分为匿名管道和非匿名管道 其中,匿名管道只能用于有"血缘关系"的进程之间进行通信,而命名管道则可以用于任意两进程的通信 此外,管道是单向的,所以2个管道就可以实现进程之间的双向通信 管道的实现原理: 我们知道,进程之间的数据是私有的,即使是父子进程,也是如此,所以,要想让2个进程共享某个数据,我们可以在指定的

IPC——匿名管道

Linux进程间通信——使用匿名管道 在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什么是管道 如果你使用过Linux的命令,那么对于管道这个名词你一定不会感觉到陌生,因为我们通常通过符号“|"来使用管道,但是管理的真正定义是什么呢?管道是一个进程连接数据流到另一个进程的通道,它通常是用作把一个进程的输出通过管道连接到另一个进程的输入. 举个例子