Linux进程间通信::匿名管道实例(一)

来源:互联网 发布:淘宝活动 编辑:程序博客网 时间:2024/06/05 09:52

管道通信分为匿名管道和有名管道,二者实质上都是内核中的缓存,而有名管道还映射了一个管道文件。

匿名管道仅能用于关系进程间:父子进程,兄弟进程

特点:单工、先进先出


通常先创建一个管道,再通过fork()函数创建一个子进程

因为fork()时,子进程也会创建一个管道。

注意两个进程需要各关闭一个管道口

实例一(父进程向子进程写入数据):

#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>


int main()
{
    int fd[2];
    if(pipe(fd) < 0){
        fprintf(stderr,"pipe create error");
exit(-1);
    }else
        printf("Create pipe successfully\n");
  
    pid_t pid;
    if((pid = fork())<0){
        perror("fork");
    }else if(pid >0){
        //this is the parent process 
close(fd[0]);
int start = 0,end = 100;
if(write(fd[1],&start,sizeof(int)) != sizeof(int)){
   perror("write error");
   exit(-1);
}


if(write(fd[1],&end,sizeof(int)) != sizeof(int)){
   perror("write error");
   exit(-1);
close(fd[1]);
}
    }else{
    //this is the child process
         close(fd[1]);
int start,end;
         if(read(fd[0],&start,sizeof(int)) < 0){
    perror("read error");
    exit(-1);
}
         if(read(fd[0],&end,sizeof(int)) < 0){
    perror("read error");
    exit(-1);
}
close(fd[0]);
printf("This is the child process!\n");
printf("start = %d,end = %d\n",start,end);
         
      }


      return 0;  

}

实例二(用管道实现命令“/bin/cat etc/passwd |grep root”)

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


char *cmd1[3]={"/bin/cat","/etc/passwd",NULL};                            //exec族函数的参数
char *cmd2[3]={"/bin/grep","root",NULL};


int main(void)
{
    int fd[2];
    if(pipe(fd)<0){
        perror("pipe error");
exit(1);
    }
    int i = 0;
    pid_t pid;

//创建进程扇
    for(;i < 2;i++){
       pid = fork();
       if(pid < 0){
           perror("fork error");
  exit(1);
       }else if(pid ==0){  //child process
           if(i==0){//child process 1 which is designed to write data
      close(fd[0]);

//dup2()用于 重定向,并关闭原文件指针

      if(dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO){
          perror("dup2 error");
      }
               //exec cat command
      if(execvp(cmd1[0],cmd1)<0){
          perror("execvp error");
          exit(1);
          }
      break;
  }
  if(i ==1){//child process 2 which is designed to read data
      close(fd[1]);

//dup2()用于 重定向,并关闭原文件指针


      if(dup2(fd[0],STDIN_FILENO) != STDIN_FILENO){
          perror("dup2 error");
      }
      //exec grep command
     if(execvp(cmd2[0],cmd2)<0){
          perror("execvp error");
  exit(1);
     }
     break;
      }
       }
else{ //parent process
           if(i == 1){
  //wait all the child process 
  close(fd[0]);
  close(fd[1]);
           wait(0);
  wait(0);
           }
       }
    }
    exit(0);
}

原创粉丝点击