Linux进程间通信---管道

IPC:
  IPC,即Inter-Process Communication,进程间通信。是进程间通信的对象,包括管道、消息队列、信号量、套接字等。关于IPC结构,首先IPC结构是内核维护的,不属于某个特定进程。IPC结构由两个东西标识:标识符(ID)和键(key)。其中,ID是IPC的内部名字,只在进程间通信使用;key是IPC的外部名字,多个进程针对同一个key调用get函数时,会得到相同的ID,即标识了同一个IPC,进程间就可以通过这个共同的IPC进行通信。
 
无名管道:
      无名管道只能用于两个具有公共祖先的进程之间,即:只能用于相关的两个进程通信,不能用于不相关的两个进程通信。常用实现函数是:int pipe(int fd[2])。pipe函数创建一个半双工管道。fd[0]用于进程读端,fd[1]用于进程写端,一个进程的fd[1]输出是另一个进程fd[0]的输入。实现例程如下:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
     int fd[2];
     char line[MAX_LINE];
     if(pipe(fd)<0);   //建立管道,fd[1]写,fd[0]读。返回0表示成功,返回-1表示失败
        err_sys("pipe erroe");
     if((pid = fork()) < 0)  //创建子进程
        err_sys("fork error");
     else if(pid > 0)  //父进程
     {
        close(fd[0]);  //关闭父进程的读端
        write(fd[1], "data", 4);  //父进程向fd[1]描述符中写
     }
     else  //子进程
     {
        close(fd[1]);  //关闭子进程的写端
        int n = read(fd[0], line, MAX_LINE);  //子进程从fd[0]描述符中读
        write(STDOUT_FIFENO, line, n);  //将读到的内容写到标准输出(cout)
     }
     exit(0);
}

  使用无名管道的优缺点:优点:相对于建立一个磁盘文件,两个进程通过磁盘读写来进行通信的方法,使用无名管道不需要创建中间临时磁盘文件,提升了进程间通信的速度。缺点:无名管道只能在具有公共祖先的两个进程间使用,即两个进程只能是父子进程或有共同父进程的两个子进程。

有名管道(FIFO):
      无名管道只能在两个相关的进程间使用(两个进程有公共祖先),但是通过FIFO,不相关的进程也能交换数据进行通信。常用的实现函数是mkfifo(path, mode),他创建一个FIFO,类似于创建一个文件,路径名path位于文件系统。FIFIO的使用类似于CS通信,write_fifo相当于客户端,向事先知道的管道发送消息;read_fifo相当于服务器端,创建一个众所周知的管道,监控管道的读端,当有数据到来时读出并处理。实现例程如下:
(1)read_fifo:
#include<stdio.h>
  #include<stdlib.h>
  #include<unistd.h>
  #include<fcntl.h>
  #include<sys/types.h>
  #include<sys/stat.h>
  int main()
  {
      int fd;
      int len;
      char buf[1024];
      if(mkfifo("/tmp/fifo1", 0666) < 0)     // 创建FIFO管道,权限为666或777
              perror("Create FIFO Failed");
      if((fd = open("fifo1", O_RDONLY)) < 0)  // 以读打开FIFO
      {
            perror("Open FIFO Failed");
            exit(1);
      }
     while((len = read(fd, buf, 1024)) > 0)   // 读取FIFO管道
            printf("Read message: %s", buf);
     close(fd);   // 关闭FIFO文件
     return 0;
}       

(2)write_fifo:

#include<stdio.h>
#include<stdlib.h>   // exit
#include<fcntl.h>    // O_WRONLY
#include <unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
    int fd;
    printf("I am %d process.\n", getpid());   // 说明进程ID
     
    if((fd = open("/tmp/fifo1", O_WRONLY)) < 0)   // 以写打开一个FIFO
    {
        perror("Open FIFO Failed");
        exit(1);
    }
    char buf[11] = "hello,fifo";
    if(write(fd, buf, 11) < 0)  // 写入到FIFO中
    {
         perror("Write FIFO Failed");
         close(fd);
         exit(1);
    }
    sleep(1);   // 休眠1秒
    close(fd);  // 关闭FIFO文件
    return 0;
}

 

 

posted @ 2018-02-23 23:11  IvanB.G.Liu  阅读(238)  评论(0编辑  收藏  举报