操作系统之进程通信——管道

Posted 苏洬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统之进程通信——管道相关的知识,希望对你有一定的参考价值。

1.熟悉wc命令

  wc命令用于计算文件的Byte数、字数、或是列数,若不指定文件名称、或是所给予的文件名为"-",则wc指令会从标准输入设备读取数据。

 参数:

  c或--bytes或--chars 只显示Bytes数。

  -l或--lines 只显示行数。

  -w或--words 只显示字数。

  --help 在线帮助。

  --version 显示版本信息

 

2.进程通信

 输入“su”后输入密码以便一下操作。

1读管道

gedit pip_read.c

  打开文件后输入:

#include <unistd.h>
#include <stdlib. h>
#include <stdio.h>
#include <str ing.h>
int main(){
  FILE *read_ fp;       //文件流指针
  char buffer [BUFSIZ+1];  //存储读取的内容
  int chars_ read;
  nenset(buffer, \' \\0\' ,sizeof(buffer));   //初始化buf ,以免后面乱码到文件中
  read_ _fp=popen("unane -a","r");      //只读方式打开连接到uname命令的管道只读方式说明:可以通过stdio 的库函数fread 读取被调用程序的输出
  if(read_ _fp!=NULL){
    chars_ read=fread(buffer ,sizeof(char) , BUFSIZ,read_ fp);
    if(chars_ read>0 )
      printf("output was:-\\n%s\\n" ,buffer);
    pclose(read_ fp);         //关闭管道
    exit( EXIT_ SUCCESS);      //正常退出
  }
    exit(EXIT_ FAILURE);       //读取失败
}

  运行截图:

    

(2)写管道

  输入命令“gedit pip_write.c”打开文件后输入:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()[
  *write_fp;
  char buffer [BUFSIZ+1];
  int chars_write;
  memset(buffer, \'\\0\' ,sizeof(buffer)); 
  sprintf(buffer ,"Once upon a time, there was...\\n");
  write_ fp=popen("wc -w" ,"w");  //通过管道(“w”参数)写入到FILE* stream
  if(write_ fp!=NULL)[
    fwrite(buffer , sizeof(char),strlen(buffer),write_fp);  //将FILE* write_ fp的数据流写入到buf中
  pclose(write_fp);
  exit(EXIT_SUCCESS);
  }
  exit(EXIT_FAILURE);
}

   运行截图:

   

3.匿名管道

 (1)生产者与消费者模型

  输入命令“gedit pipe.c”打开文件后输入:

#include <unistd.h>
#include <stdlib. h>
#include <stdio. h>
#include <string .h>
int main()[
  int data_ processed;
  int file_ pipes[2];//存储两个文件描述符 0 1
  const char some_data[]="123";
  char buffer[BUFSIZ+1]; 
  memset(buffer , \'\\0\' , sizeof(buffer));
  /*pipe创建管道,并向数组写入2个文件描述符,这两个文件描
  述符关系密切(父子进程),用文件描述符file_ pipes[1]向管道中写数据,用文件描述符file_ pipe[0]从管道中读数据。*/
  if(pipe(file_pipes)==0){
    //用file_ pipes [1]文件描述符向管道中写数据
    data_ processed= write(file_pipes[1],some_data, strlen(some_data));
    printf("Wrote %d bytes\\n" ,data_processed);
    data_ processed=read(file_pipes[0], buffer , BUFSIZ); 
    printf("Read %d bytes: %s\\n" ,data_ processed , buffer);
    exit( EXIT_SUCCESS);
  }   exit(EXIT_FAILURE);
}

   运行截图:

     

 (2)父子进程通信

  输入命令“gedit pipe_fork.c”打开文件后输入:

#include <unistd .h>
#include <stdlib.h>
#include <stdio. h>
#include <string.h>
int main( ){
  int data_processed;
  int file_pipes[2];
  const char some_data[]="123";
  char buffer [BUFSIZ+1];
  pid_t pid;
  memset(buffer , \'\\0\',sizeof(buffer));
  if(pipe(file_pipes)==0){
    pid=fork();
    if(pid == -1){          //创建子迸程失敗
      fprintf(stderr ,"Fork failure");
    exit(EXIT_FAILURE);
    if(pid==0){            //子迸程
      sleep(1);
      data_processed=read(file_ pipes[0],buffer, BUFSIZ);
      printf("Read %d bytes: %s\\n", data_processed, buffer);       close(file_pipes[1]);    //关闭读端       exit(EXIT_SUCCESS);     }     else{ /              /父迸程       data_processed=write(file_pipes[1],some_data, strlen(some_data));       printf("Wrote %d bytes\\n" ,data_processed);       close(file_pipes[0]);     //写入成功,关闭写端     }
  }   exit(EXIT_ SUCCESS);
}

   运行截图:

    

 4.命名管道

(1)shell命令创建

  

  mkfifo命令解释见下代码注释

 (2)程序创建

#include <unistd. h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char *argv[]){
/*int mkfifo(const char * pathname , mode_t mode);
nkfifo()会依参数pathnane(路径)建立特殊的FIFo文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask)因此umask值也会影响到FIFo文件的权限。*/
int res = mkfifo("/my_fifo" ,0777);
if(res==0)
printf("FIFO createdn");
exit(EXIT_SUCCESS);
}

 (3)读空 

cat < /fifo  //编译之后的输出文件的路径

(4)输入(需要用另一个终端)

echo "hello,word" > /fifo

  运行结果:

  

以上是关于操作系统之进程通信——管道的主要内容,如果未能解决你的问题,请参考以下文章

多进程编程之进程间通信

linux c之通过管道实现兄弟间进程通信:

操作系统之进程通信——管道

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

简述Linux进程间通信之命名管道FIFO

进程通信 之 管道 标准流管道