进程间通信

青旅半醒 2021-08-30 22:05 621阅读 0赞

进程间通信

    1. 前言
    1. 使用文件实现进程间的通信
    1. 使用管道实现进程间的通信
    1. 共享内存
    1. 以上三种通信方式的区别
    1. 信号量
    1. 信号
    1. 消息队列

1. 前言

  1. 进程间通信的方式可谓是面试热点,面试的时候也曾有幸被问到。当时呢是背的面试题,对进程间通信的原理也不是很了解。今天呢就深入了解进程间的通信。
  2. 首先捋一捋进程间的通信有哪几种方式:
  1. socket
  2. 文件
  3. 管道
  4. 共享内存
  5. 信号
  6. 信号量
  7. 消息队列

2. 使用文件实现进程间的通信

  1. 文件:以磁盘作为信息的载体。
  2. 示例:
  • 服务器:提供日期时间服务。
  • 客户端:读取服务器提供的数据或信息。

    基本思想:

  • 服务器进程将数据写入文件

  • 客户端进程从文件中读出数据。

    // server.c

    include

    include

    include

    include

    include

    include

    int main(int argc, char * argv[])
    {

    1. int fd;
    2. time_t now;
    3. char *message;
    4. if (argc!=2)
    5. {
    6. printf("errror usage ! \nusage: server filename\n") ;
    7. exit(1);
    8. }
    9. if((fd=open(argv[1],O_CREAT|O_WRONLY|O_TRUNC , 0644))==-1)
    10. {
    11. perror("open");
    12. exit(1);
    13. }
    14. while(1)
    15. {
    16. time (&now);
    17. message=ctime (&now) ;
    18. // lseek 改变文件读写指针的位置
    19. // SEEK_SET 文件的开始
    20. // 因为这里 time 的字节数始终相等,所以覆盖掉之前写的数据,每次文件中只会保存最新的数据
    21. if( (lseek(fd,0,SEEK_SET))==-1)
    22. {
    23. perror("lseek") ;
    24. exit(1) ;
    25. }
    26. if(write (fd, message, strlen(message))==-1)
    27. {
    28. perror("write");
    29. exit(1) ;
    30. }
    31. sleep(1);
    32. }

    }

    // client.c

    include

    include

    include

    include

    int main(int argc, char *argv[])
    {

    1. int fd, len;
    2. char buf[128] ;
    3. if(argc!=2)
    4. {
    5. printf("error usage!\nusage: client filename") ;
    6. exit(1);
    7. }
    8. if((fd=open(argv[1],O_RDONLY))==-1)
    9. {
    10. perror("open");
    11. exit(1);
    12. }
    13. while((len=read(fd, buf, 128) )>0)
    14. {
    15. write(1, buf ,len) ;
    16. }
    17. close(fd) ;

    }

在这里插入图片描述

3. 使用管道实现进程间的通信

  1. 管道:以内核空间存放信息。
  2. 管道又分为有名管道和匿名管道,有名管道用于无亲缘关系的进程间通信,而匿名管道则用于有亲缘关系进程间通信。
  3. 示例:
  • 服务器:提供日期时间服务。
  • 客户端:读取服务器提供的数据或信息。

    基本思想:

  • 服务器进程建立命名管道,将数据写入管道。

  • 客户端进程从管道中读出数据。

    // server.c

    include

    include

    include

    include

    include

    include

    include

    int main(int argc, char * argv[])
    {

    1. int fd;
    2. time_t now ;
    3. char * message;
    4. if(argc!=2)
    5. {
    6. printf("errror usage! \nusage: server fifoname\n");
    7. exit(1);
    8. }
    9. unlink(argv[1]);
    10. // 创建有名管道
    11. if(mkfifo(argv[1], 0644)==-1)
    12. {
    13. perror("mkfifo") ;
    14. exit(1) ;
    15. }
    16. if((fd=open(argv[1],O_WRONLY))==-1)
    17. {
    18. perror("open");
    19. exit(1) ;
    20. }
    21. while(1)
    22. {
    23. time (&now);
    24. message=ctime(&now) ;
    25. if(write (fd, message, strlen(message))==-1)
    26. {
    27. perror("write") ;
    28. exit(1) ;
    29. }
    30. sleep(1);
    31. }

    }

    // client.c

    include

    include

    include

    include

    int main(int argc, char *argv[])
    {

    1. int fd, len;
    2. char buf[128] ;
    3. if(argc!=2)
    4. {
    5. printf("error usage!\nusage: client filename") ;
    6. exit(1);
    7. }
    8. if((fd=open(argv[1],O_RDONLY))==-1)
    9. {
    10. perror("open");
    11. exit(1);
    12. }
    13. while((len=read(fd, buf, 128) )>0)
    14. {
    15. write(1, buf ,len) ;
    16. }
    17. close(fd) ;

    }

在这里插入图片描述

4. 共享内存

  1. 共享内存是`System V IPC`的一种,不依赖于进程的存在而存在。
  2. 以下三种类型的进程通信方式(`IPC`)合称为`System V IPC`
  • System V 消息队列
  • System V 信号量
  • System V 共享内存区

    共享内存的通信效率比管道的效率更高。

    共享内存的通信原理图如下所示:

在这里插入图片描述
共享内存的使用

  1. 创建(shmget
  2. 连接(shmat
  3. 读写(strcpymemcpy
  4. 解开连接(shmdt
  5. 删除(shmctl

    使用共享内存通信调用上方的函数即可实现。

5. 以上三种通信方式的区别

  1. **文件**
  • 权限:文件由服务器创建,客户端进程必须具有读文件的权限。.
  • 多个用户:多个客户端程序可以从文件中读取数据。
  • 读写冲突:存在,读写操作需要互斥进行。

    1. **管道**
  • 权限:服务器创建管道并写入数据;客户端读取管道中的数据。

  • 多个用户:命名管道是一个内核中的队列,排队首的第-个读进程会将数据取走。
  • 读写冲突: 管道传输数据需要读写双方同时打开管道。多个读进程会排队读取数据;读写进程在管道的不同端,不存在冲突。

    1. **共享内存**
  • 权限:共享内存为属主、组用户和其他用户设置了权限,服务器端拥有共享内存,客户端进程要能够读取共享内存。

  • 多用户:多个客户端可以同时从共享内存段中读取数据。
  • 读写冲突:存在。客户端读取数据时,有可能服务器端在写数据,因此需要辅助其他控制手段,保证读写共享内存段互斥进行。
  • 访问速度:

    文件:外存介入
    命名管道:用户态和内核态的转换
    共享内存:外存有可能介入

  • 使用范围:

    命名管道、共享内存:本机上的进程
    文件:不同机器上的进程

6. 信号量

  1. 信号量是一个内存变量,可以被系统中的任何进程所访问。
  2. 多个进程使用信号量来协调对临界资源的访问。
  3. `Linux`中信号量是以集合的形式存在的,一个集合中存在着多个信号量。
  4. 信号量的使用:
  1. 创建信号量集(semget
  2. 执行PV操作(semop
  3. 删除信号量集合(semctl

    信号量机制是为了协调多个进程对资源的使用,semop操作对应于操作系统中的PV原语。但与操作系统中的信号量有所不同:

  4. 信号量机制中最小单位是信号量集,并非单个整型数,信号量集中的信号量数目在创建该集合时指定。

  5. 创建信号量集与对其赋初值这两个操作是分开的,并非合在一起的原子操作,这是一个致命的弱点。
  6. 有些程序在终止时并没有释放已经分配给它的信号量集,SEM_ UNDO标识就是用来处理这些情况的。

7. 信号

  1. 信号是内核发送给某一进程的一种消息。
  2. 如一个正在运行的程序,我们按下`Ctrl + C`就可以终止该程序。
  3. 信号机制`Linux`系统中用于进程之间相互通信或操作的一种机制。

在这里插入图片描述

8. 消息队列

  1. 消费队列,生产者、消费者的模式。如`kafka``RabbitMQ`等,一个进程复杂生产消息,另一个进程复杂消费消息。

发表评论

表情:
评论列表 (有 0 条评论,621人围观)

还没有评论,来说两句吧...

相关阅读

    相关 进程通信

    管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道“我们之前说进程间通信的本质是让不同的进程看到同一份资源,管道就是其中...

    相关 进程通信

    1 引言 \---- 进程间通信的主要目的是实现同一计算机系统内部的相互协作的进程之间的数据共享与信息交换,由于这些进程处于同一软件和硬件环境下,利用操作系统提供的的编程接口

    相关 进程通信

    进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号

    相关 进程通信

    二、进程间通信方式 线程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的

    相关 进程通信

    进程间通信(IPC,Inter-Process Communication),是指两个或两个以上的进程之间传递数据或信号的一些技术或方法。进程是计算机系统分配资源的最小单位,每

    相关 进程通信

    进程间通信的基本概念 进程间通信意味着两个不同进程间可以交换数据,操作系统中应提供两个进程可以同时访问的内存空间。 通过管道实现进程间通信 基于管道(P

    相关 进程通信

    程序员必须让拥有依赖关系的进程集协调,这样才能达到进程的共同目标。可以使用两种技术来达到协调。第一种技术在具有通信依赖关系的两个进程间传递信息。这种技术称做进程间通信(inte

    相关 进程通信

    进程间通信 1. 前言 2. 使用文件实现进程间的通信 3. 使用管道实现进程间的通信 4. 共享内存 5. 以上三种通信方式的区别