[Linux] Process address space

[Linux] Process address space

The concept of process address space

As a computer software and hardware resource manager, the operating system must of course manage the memory allocation of each process. Therefore, it must have a data structure that describes the memory allocation of each process. This kernel data structure is the process address space. In the Linux operating system, the variable name of this data structure is mm_struct.

Implementation of process address space

In order to better manage memory allocation, the implementation of mm_struct adopts the following strategy:

  • As a data structure that describes memory allocation, it describes the entire memory space.
  • Use continuous linear addresses to describe addresses in memory.
  • The addresses described are all virtual addresses.

The pseudocode of mm_struct is as follows:

struct mm_struct
{
    
    
    long code_begin; //代码区起始地址
    long code_end;	 //代码区结束地址
    //...
    long brk_begin;  //堆区起始地址
    long brk_end;	 //堆区结束地址
    long brk_begin;  //栈区起始地址
    long brk_end;	 //栈区结束地址
}

Note: Since the process address space is a memory address described by continuous linear virtual addresses, each area in the memory can be distinguished by the start address and end address. As shown below:

image-20230826134746803

Although the process address space describes a virtual address, the process still needs to find its own data and code at the actual address in the memory. Therefore, the operating system uses mapping to convert the virtual address into an actual memory address. A tool called a page table is used during mapping. The page table records the mapping between virtual addresses and actual memory addresses, as follows:

image-20230826135906135

Understanding copy-on-write

First write the following code to observe the copy-on-write phenomenon:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>

int main()
{
    
    
  int val = 100;
  pid_t id = fork();
  assert(id >= 0);
  if (id == 0)
  {
    
    
    //子进程
    while(1)
    {
    
    
      printf("我是子进程,pid:%d, ppid:%d, val:%d, &val:%p\n", getpid(), getppid(), val, &val);
      sleep(1);
      val = 200;
    }
  }
  else if (id > 0)
  {
    
    
    while(1)
    {
    
    
      printf("我是父进程,pid:%d, ppid:%d, val:%d, &val:%p\n", getpid(), getppid(), val, &val);
      sleep(1);
    }
  }
  return 0;
}

Compile and run the above code to see the phenomenon:

image-20230826141508478

  • After the child process modifies the value of the val variable, the change in the val value of the child process does not affect the val value of the parent process.
  • The val addresses of the parent and child processes are the same, but the values ​​are different.

The above parent-child processes share the same variable in the code. When either party attempts to write, both parties will each use a copy, which is called copy-on-write.

First of all, since the addresses in the process address space are all virtual addresses, the data read by the parent and child processes at the same address appears to be different. When the child process is created, the process address space and page table used are copied from the parent process, as follows:

image-20230826142401503

When the child process modifies val, the operating system will re-open a space for the child process to record the modified value, and then modify the actual address mapped in the page table to implement copy-on-write, as follows:

image-20230826142642452

Why is there a process address space?

In order to understand why there is a process address space, we must first understand two things:

The essence of malloc

Since memory resources are limited, in order to reduce the waste of memory space, the operating system only fills in the address in the virtual address of the page table when applying for memory with malloc, and the actual memory address in the page table is vacant. When waiting for the process to use it, allocate a piece of space and fill in the actual address into the page table. This avoids the waste of space caused when a process applies for space but does not use the space.

The address space of the executable program

When the source code is compiled, the code and data are compiled according to the corresponding addressing method that has been programmed in the virtual address space.

Under Linux systems, you can use objdumop -S 可执行程序名the virtual address of the program to view:

image-20230826155041035

After the process starts executing, the CPU first executes the virtual entry address, which also contains the address. The CPU will start jumping the page table through the content recorded in the entry address, and then execute the code and data of the process normally. .

Why is there a process address space?

First, we need to know how the operating system works if there is no process address space. When there is no process address space, there will be no page table. After the process is loaded into the memory, the CPU executes it in the order of the code inside the process. as follows:

image-20230826150931606

  • First, in this case, when executing the code of the process, if there is a problem with the code and a wild pointer memory access operation occurs, the CPU will also perform an incorrect access operation. With the process address space, there is also a page table. When accessing any data, it must be mapped through the page table. The page table not only stores the mapping relationship of the address, but also stores the read address of a certain address. Write permissions, etc., if a wild pointer is used, the page table will intercept it.
  • Secondly, in this case, if the process wants to partition the data according to the global area, static area and other partitions, it must find the actual whole block address in the physical memory for partitioning, so that the management of the process and the management of the memory Collaborative work is required. But with the process address space and page table, the process only needs to know whether the addresses in the process address space can be divided according to regions, and the physical memory only needs to find the space, no matter where it is in the memory, because in the end All data accesses are mapped through page tables, and the same process management and memory management are decoupled.
  • Third, in this case, code and data need to be distinguished separately. With the process address space and page table, a process only needs to access code and data through the process address space. In all process address spaces, the partition addresses of code and data are the same, so that all processes can see The view is the same when it comes to your own process address space.

Summarize:

  1. Prevent random access to addresses and protect physical memory and other processes.
  2. Decouple process management and memory management.
  3. Give all processes a unified view of code and data.

Guess you like

Origin blog.csdn.net/csdn_myhome/article/details/132522396