Linux传统跨进程通信原理

文章目录

  • 前言
  • 一、进程隔离
  • 二、进程空间划分:用户空间(User Space)/内核空间(Kernel Space)
  • 三、系统调用:用户态与内核态
  • 四、Linux下传统IPC跨进程通信原理
    • 1、发送进程通过系统调用,将需要发送的数据拷贝到Linux进程的内核空间中的缓存区(数据拷贝1次,通过copy_from_user())
    • 2、内核服务程序唤醒接收进程的接收线程,通过系统调用将数据发送到接收进程的用户空间中,最终完成数据发送(数据拷贝2次,通过copy_to_user()),最终实现进程间的用户空间的数据交互
    • 3、缺点

前言

Linux中跨进程通信涉及到一些基本概念:

  • 进程隔离
  • 进程空间划分:用户空间(User Space)/内核空间(Kernel Space)
  • 系统调用:用户态/内核态

一、进程隔离

操作系统中,进程与进程间内存是不共享的。两个进程就像两个平行的世界,A 进程没法直接访问 B 进程的数据,这就是进程隔离的通俗解释。A 进程和 B 进程之间要进行数据交互就得采用特殊的通信机制:进程间通信(IPC)。

进程隔离为了保证 安全性 & 独立性,一个进程不能直接操作或者访问另一个进程,即Android的进程是相互独立、隔离的

二、进程空间划分:用户空间(User Space)/内核空间(Kernel Space)

现在操作系统都是采用的虚拟存储器,对于 32 位系统而言,它的寻址空间(虚拟存储空间)就是 2 的 32 次方,也就是 4GB。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也可以访问底层硬件设备的权限。为了保护用户进程不能直接操作内核,保证内核的安全,操作系统从逻辑上将虚拟空间划分为用户空间(User Space)和内核空间(Kernel Space)。针对 Linux 操作系统而言,将最高的 1GB 字节供内核使用,称为内核空间;较低的 3GB 字节供各进程使用,称为用户空间。

简单的说就是,内核空间(Kernel)是系统内核运行的空间,用户空间(User Space)是用户程序运行的空间。为了保证安全性,它们之间是隔离的。

一个进程空间分为 用户空间 & 内核空间(Kernel),即把进程内 用户 & 内核 隔离开来
1、进程间,用户空间的数据不可共享,所以用户空间 = 不可共享空间
2、进程间,内核空间的数据可共享,所以内核空间 = 可共享空间
所有进程共用1个内核空间

Linux传统跨进程通信原理_第1张图片

三、系统调用:用户态与内核态

虽然从逻辑上进行了用户空间和内核空间的划分,但不可避免的用户空间需要访问内核资源,比如文件操作、访问网络等等。为了突破隔离限制,就需要借助系统调用来实现。系统调用是用户空间访问内核空间的唯一方式,保证了所有的资源访问都是在内核的控制下进行的,避免了用户程序对系统资源的越权访问,提升了系统安全性和稳定性。

Linux 使用两级保护机制:0 级供系统内核使用,3 级供用户程序使用。

当一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态(内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。

当进程在执行用户自己的代码的时候,我们称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。

系统调用主要通过如下两个函数来实现:

copy_from_user() //将数据从用户空间拷贝到内核空间
copy_to_user() //将数据从内核空间拷贝到用户空间

Linux传统跨进程通信原理_第2张图片

四、Linux下传统IPC跨进程通信原理

1、发送进程通过系统调用,将需要发送的数据拷贝到Linux进程的内核空间中的缓存区(数据拷贝1次,通过copy_from_user())

2、内核服务程序唤醒接收进程的接收线程,通过系统调用将数据发送到接收进程的用户空间中,最终完成数据发送(数据拷贝2次,通过copy_to_user()),最终实现进程间的用户空间的数据交互

Linux传统跨进程通信原理_第3张图片

3、缺点

  • 性能低下,一次数据传递需要经历:内存缓存区 --> 内核缓存区 --> 内存缓存区,需要 2 次数据拷贝;
  • 接受数据的缓存要由接收方提供,但接收方却不知道到底要多大的缓存才满足需求(一般解决方法:开辟尽可能大的空间 或者先调用API接收消息头获得消息体大小,再开辟适当的空间接收消息体。但前者浪费空间,后者浪费时间)

你可能感兴趣的:(android,linux,服务器,网络)