zoukankan      html  css  js  c++  java
  • Linux下进程间管道通信小作业

    在进行这次作业之前,我们先来看看什么是管道吧!

    管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。

    有名管道叫named pipe或者FIFO(先进先出),可以用函数mkfifo()创建。

    Linux管道的实现机制

    在Linux中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:

    ·      限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。

    ·      读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。

    注意:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。

    在网上看到这么个小作业,用来学习Linux管道,妥妥的。

    /*说明:一次作业,目的是了解Linux下进程和进程间通过管道通信
    *          没考虑复杂算法和其他一些可能出现的问题
    *功能:统计2个文本文件的字数和,2个参数分别为两文件名
    *描述:父进程启动,开启子进程,子进程统计一个文本的字数,
    *          待子进程结束,父进程统计另一个,在父进程中计算和打印统计结果
    */

     1 #include <unistd.h>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 
     5 int count(FILE*);
     6 int main(int argc, char *argv[])
     7 {
     8     int num1,num2,totalnum;    //文件1,文件2,中的字数和总字数
     9         FILE *fpin1,*fpin2; //两个文件指针
    10         if(argc==3)
    11      { 
    12         fpin1=fopen(argv[1],"r");
    13         fpin2=fopen(argv[2],"r");
    14      }
    15     else if(argc>3) 
    16         printf("Too many args!!
    ");
    17     else
    18         printf("Input a file two file names to count their total words!!
    ");
    19 
    20     pid_t child;
    21     int status;
    22     int fds[2];
    23     int buf1[1],buf2[1];
    24     pipe(fds);  //开启管道
    25         if((child=fork())==-1)
    26      {
    27         perror("fork");
    28         exit(EXIT_FAILURE);
    29      }
    30     else if (child==0) //子进程
    31         {
    32         close(fds[0]);
    33         buf1[0]=count(fpin1);
    34         write(fds[1],buf1,sizeof(int));    //结果写入管道
    35                 exit(1);
    36      }
    37     else //父进程
    38         {
    39         wait(0);  //等待子进程结束
    40                 read(fds[0],buf2,sizeof(int)); //从管道中读子进程返回结果
    41                 num1=buf2[0];
    42         num2=count(fpin2);
    43         totalnum=num1+num2;
    44         printf("There are %d words in file1
    ",num1);
    45         printf("There are %d words in file2
    ",num2);
    46         printf("There are %d words in total
    ",totalnum);
    47         exit(1);
    48      }
    49     //关闭文件
    50         fclose(fpin1);
    51     fclose(fpin2);
    52     return 0;
    53 }
    54 
    55 //文件字数统计函数
    56 int count(FILE* fpin)
    57 {
    58     int num=0;
    59     char ch;
    60     int start=0; //字是否开始
    61         int end=0;     //字是否结束
    62         while(!feof(fpin))
    63      {
    64         ch=getc(fpin);
    65         if((ch>=65&&ch<=90)||(ch>=97&&ch<=122)) //字以字母开头
    66                         start=1;
    67         if(ch==10||ch==13||ch==9||ch==32)  //字以换行,回车,指标符,空格结束
    68                         end=1;
    69         if(start==1&&end==1) //字开始并结束了字数加1
    70                 {
    71             num++;
    72             start=0; //清0准备下一个统计
    73                         end=0;
    74          }
    75      }
    76     return num;
    77 }
    View Code
  • 相关阅读:
    [转]读取并修改App.config文件
    [转]线程和进程的概念
    实习日志(3)
    实习日志2
    实习小感,回学校啦~~~~
    请教LUA高手一段代码,希望帮忙谢谢!
    实习的日子
    vs显示 error LNK2019: 无法解析的外部符号 _main解决办法
    创建一个新窗口进程并返回进程ID号和进程的主线程ID号
    显示基本图形界面第一天
  • 原文地址:https://www.cnblogs.com/victorruan/p/3470646.html
Copyright © 2011-2022 走看看