Linux进程间通信——匿名管道

目录

  • 通信介绍
    • 目的
    • 进程间通信发展
  • 进程间通信分类
  • 管道
  • 匿名管道
    • 匿名管道的特点
    • 匿名管道读写的4种情况

通信介绍

进程之间可能会存在特定的协同工作的场景,为此一个进程要把自己的数据交付给另一个进程,让其进行处理,而进程是具有独立性的,一个进程看不到另一个进程的资源,因此交互数据成本一定很高。为了完成进程间的通信,首先得先有一份各进程都能看到公共资源,而这里的资源指的就是内存,且它属于操作系统(因为当它属于操作系统时才能让各个进程都能看到),换言之进程间通信的前提本质是由OS参与,提供有一份所有进程能看到的公共资源(可能以文件方式提供,也可能以队列的方式,也可能提供的就是原始的内存块,这也是通信方式有很多种的原因)

目的

  • 数据传输:一个进程需要将它的数据发送给另一个进程
  • 资源共享:多个进程之间共享相同的资源
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)
  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug)进程,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够即使知道它的状态改变

进程间通信发展

  • 管道
  • Ststem V进程间通信
  • POSIX进程间通信

进程间通信分类

管道

  • 匿名管道pipe
  • 命名管道
    System V IPC
  • System V 消息队列
  • System V 共享内存
  • System V信号量
    POSIX IPX
  • 消息队列
  • 共享内存
  • 信号量
  • 条件变量
  • 读写锁

管道

管道是Unix中最古老的进程间通信的形式,我们把从一个进程连接到另一个进程的一个数据流成为一个管道

匿名管道

我们首先来思考一个问题,父子进程是两个独立进程吗?答案是肯定的,也就是说父子进程具有独立性,因此它们之间不能直接交换资源。当我们希望父子进程进行通信时,我们就可以使用匿名管道,匿名管道用于进程之间通信,且仅限于本地父子进程之间通信。
我们先来看看pipe的函数接口,它可以创建一个匿名管道
Linux进程间通信——匿名管道_第1张图片

接下来我们写一个程序来体验一下匿名管道的使用,我们会创建一个子进程,并要求在子进程向管道写入数据,父进程从管道读取数据

#include 
  2 #include <unistd.h>
  3 #include <stdlib.h>                                                                                                                   
  4 #include <string.h>
  5      
  6 int main()                      
  7 {                                       
  8   int pipefd[2] = {0};
  9   if (pipe(pipefd) != 0)
 10   {         
 11     perror("pipefd");
 12     return 1;      
 13   }        
 14   // pipe[0] 读取端
 15   // pipe[1] 写入端
 16   // 目标father write child read                  
 17   if (fork() == 0)
 18   {  
 19     // 子进程
 20     close(pipefd[0]);
 21     while(1)       
 22     {
 23      char str[] = "hello ssj\n";
 24      write(pipefd[1], str, strlen(str));
 25      sleep(1);
 26     }    
 27     exit(0);
 28   }         
 29   close(pipefd[1]);
 30   while (1)
 31   {        
 32     char buf[64];
     ssize_t s = read(pipefd[0], buf, sizeof(buf));
 34     if (s == 0)
 35     {
 36       break; 
 37     }
 38     else if (s > 0)
 39     {
 40       buf[s] = 0;
 41       printf("child say : %s", buf);
 42     }
 43     else 
 44     {
 45       break;
 46     }
 47   }
 48   return 0;
 49 }                      

程序运行后结果如下
Linux进程间通信——匿名管道_第2张图片

匿名管道的特点

1.管道是一个只能单向通信的通信信道
2.管道是面向字节流的
3.仅限于父子通信
4.管道自带同步机制,原子性输入
5.管道的声明周期是随进程的(管道是一个文件,只能被当前进程打开,相关进程退出了,会被OS自动关闭)

匿名管道读写的4种情况

1.读端不读或者读的慢,写端要等读端
2.读端关闭,写端收到SIGPIPE信号直接终止
3.写端不写或者写得慢,读端要等写端
4.写端关闭,读端读完pipe内部的数据然后再读,直到0,表明文件结尾

你可能感兴趣的:(Linux,操作系统,unix,服务器,linux)