• 【Linux进程间通信】 管道


    IPC机制:管道,信号量,共享队列,消息队列, 套接字。

    管道,信号量,共享队列,消息队列,都只能在同一台主机上通信。
    而套接字可以在不同电脑上通信。
    在内核空间开辟。
    管道大小
    通过ulimit -a 来查看 也可以修改
    在这里插入图片描述

    管道

    管道通信的时候是半双工的。

    有名管道

    可以在同一台主机上面的任意进程进行通信

    首先 先使用 mkfifo + 文件名 创建管道文件
    在这里插入图片描述

    管道文件的大小为0
    在这里插入图片描述

    它不在磁盘上开辟空间,它是在内存上面开辟的。磁盘上面存放的只是这个文件的属性信息,如它是谁创建的,它是上面时候创建的,等等。
    对管道操作的时候必须同时两个进程对其进行操作
    一个的话就会阻塞住
    在这里插入图片描述
    案例
    一个进程往管道中写,一个进程从管道中读
    wfile.c

    #include
    #include
    #include
    #include
    int main()
    {
      int fd = open("fifo",O_WRONLY);
      if(-1 ==  fd)
      {
       std::cout<<"open erro"<<std::endl;
       exit(-1);
      } 
    
      while(1)
      {
       std::cout<<"please input"<<std::endl;
       char buff[128]={0};
       std::cin>>buff;
       write(fd,buff,strlen(buff));
       if(strncmp(buff,"end",3)==0)
       {
         break;
       }
       
      }
    
      close(fd);
      exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    rfile.c

    #include
    #include
    #include
    #include
    int main()
    {
      int fd = open("fifo",O_RDONLY);
      if(-1 ==  fd)
      {
       std::cout<<"open erro"<<std::endl;
       exit(-1);
      } 
    
      while(1)
      {
       char buff[128]={0};
       int n = read(fd,buff,127);
       if(n <= 0 ||strncmp(buff,"end",3)==0)
       {
         break;
       }
       std::cout<<buff<<std::endl;
      }
    
      close(fd);
      exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    演示
    在这里插入图片描述
    在这里插入图片描述

    无名管道

    只能在父子进程之间通信

    向管道中写入的数据永远在内存中

    有名管道可以在任意管道中通信,而无名管道只能在父子进程中通信

    管道为满,写操作会阻塞
    管道为空,读操作会阻塞

    父进程往管道中写,子进程从管道中读

    #include
    #include
    #include
    #include
    int main()
    {
       int fd[2];
       int res = pipe(fd);
       if(-1 == res )
       {
        std::cout<<"pipe erro"<<std::endl;
        exit(-1);
       }
       pid_t pid = fork();
       if(-1 == pid)
       {
        std::cout<<"fork erro"<<std::endl;
        exit(-1);
       }
       if(pid == 0)
       {
         close(fd[1]);
         char buff[128]={0};
         int n = read(fd[0],buff,127);
         std::cout<<buff<<std::endl;
         close(fd[0]);
       }else
       {
         close(fd[0]);
         write(fd[1],"hello",5);
         close(fd[1]);
       }
        exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    演示:
    在这里插入图片描述

    在这里插入图片描述
    管道实际就是有两个指针,一个负责写,一个负责读,两个指针之间的则为管道中暂存的数据,当两个指针指向同一个位置时,则表示此时管道为空,当负责写的指针写的管道的末尾没有空间时,则会返回到首部去进行写。

    在使用无名管道时为什么要关闭不使用的另外一端?

    假如说在使用读的时候,没有关闭写,当另一端的写端关闭时,而此时进行read的时候,它检测到还有一个写端,并不会立即返回0,而是进行阻塞。

  • 相关阅读:
    eslint+stylelint+prettier全流程配置
    央国企、金融信创改造必备的Windows AD域控国产替代方案
    *p++ 与 (*p)++
    Gradle基础
    STM32移植SFUD
    Java安全--篇1-反射
    docker内部无法使用ping等网络工具解决方案
    【Linux】最新CentOS8内核升级
    Week 5 - Neural Networks and Neural Language Models
    基于Python+tkinter实现一个简易计算器桌面软件
  • 原文地址:https://blog.csdn.net/aoeaoao/article/details/125148314