zoukankan      html  css  js  c++  java
  • 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.
    ", 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;
    }
  • 相关阅读:
    求全排列,调用C++函数
    ZOJ 3508 (the war)
    HDU 1285
    SDUT--枚举(删数问题)
    SDUT--进制转换
    位运算
    [NOI2015]软件包管理器
    列队[noip2017]
    [APIO2007]动物园
    [NOI2001]炮兵阵地
  • 原文地址:https://www.cnblogs.com/ladawn/p/8463811.html
Copyright © 2011-2022 走看看