物理地址空间与虚拟地址空间的区别

208 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

  • 物理地址空间与虚拟地址空间的区别

    大小

    • 物理地址空间的大小是由地址总线决定的:比如32位系统,物理地址空间:4G=2324G = 2^{32}
    • 进程的虚拟地址空间是物理地址空间大小相同。比如32位系统,他的进程虚拟空间大小就是 4G4G

    寻址方式不同

    • 物理地址空间的地址是可以直接寻址内存
    • 虚拟地址空间的地址需要经过内存管理单元MMU(memory manger unit) 翻译得物理地址,再去寻址内存
  • 什么时候发生虚拟内存向物理内存的映射

    初始化的时候会建立一部分映射

      #include <iostream>
    
      int main(int argc, char const *argv[])
      {
        int a =10;
        int b =1;
    
        std::cout<<(a + b)<<std::endl;
        return 0;
      }
    

    对于上述代码,编译会得到的信息如下:

      $ g++ -static main.cc -o main.elf && readelf -l main.elf 
    
      Elf 文件类型为 EXEC (可执行文件)
      Entry point 0x404b00
      There are 10 program headers, starting at offset 64
    
      程序头:
        Type           Offset             VirtAddr           PhysAddr
                      FileSiz            MemSiz              Flags  Align
        LOAD          0x0000000000000000 0x0000000000400000 0x0000000000400000
                      0x00000000000005f0 0x00000000000005f0  R      0x1000
        LOAD          0x0000000000001000 0x0000000000401000 0x0000000000401000
                      0x000000000017185d 0x000000000017185d  R E    0x1000
        LOAD          0x0000000000173000 0x0000000000573000 0x0000000000573000
                      0x00000000000533f9 0x00000000000533f9  R      0x1000
        LOAD          0x00000000001c6940 0x00000000005c7940 0x00000000005c7940
                      0x000000000000bc10 0x0000000000010268  RW     0x1000
        NOTE          0x0000000000000270 0x0000000000400270 0x0000000000400270
                      0x0000000000000020 0x0000000000000020  R      0x8
        NOTE          0x0000000000000290 0x0000000000400290 0x0000000000400290
                      0x0000000000000044 0x0000000000000044  R      0x4
        TLS           0x00000000001c6940 0x00000000005c7940 0x00000000005c7940
                      0x0000000000000068 0x00000000000000b8  R      0x8
        GNU_PROPERTY  0x0000000000000270 0x0000000000400270 0x0000000000400270
                      0x0000000000000020 0x0000000000000020  R      0x8
        GNU_STACK     0x0000000000000000 0x0000000000000000 0x0000000000000000
                      0x0000000000000000 0x0000000000000000  RW     0x10
        GNU_RELRO     0x00000000001c6940 0x00000000005c7940 0x00000000005c7940
                      0x00000000000096c0 0x00000000000096c0  R      0x1
    

    对程序中的变量进行读写时,发生缺页中断会建立映射

Linux 进程间通信方式

Linux 进程间通讯方式有:管道,信号,消息队列,共享内存,套接字共六种。参考地址

管道

分为有名管道(PIPE)和无名管道(FIFO)。管道都是半双工的,数据只能单向流动。PIPE和FIFO用来实现进程间相互发送非常短小的、频率很高的消息;**这两种方式通常适用于两个进程间的通信。

无名管道:只能在具有亲缘关系的进程间使用,利用的是 fork 函数调用之后的两个管道文件描述符 fd[0], fd[1]都保持打开,一对这样的文件描述符只能保证父、子进程间的一个方向的数据传输,父子进程必须有一个关闭 fd[0],另一个关闭 fd[1]