[Linux] Espacio de direcciones de proceso

[Linux] Espacio de direcciones de proceso

El concepto de espacio de direcciones de proceso.

Como administrador de recursos de software y hardware de una computadora, el sistema operativo debe, por supuesto, administrar la asignación de memoria de cada proceso. Por lo tanto, debe tener una estructura de datos que describa la asignación de memoria de cada proceso. Esta estructura de datos del núcleo es el espacio de direcciones del proceso. En el sistema operativo Linux, el nombre de la variable de esta estructura de datos es mm_struct.

Implementación del espacio de direcciones de proceso.

Para gestionar mejor la asignación de memoria, la implementación de mm_struct adopta la siguiente estrategia:

  • Como estructura de datos que describe la asignación de memoria, describe todo el espacio de memoria.
  • Utilice direcciones lineales continuas para describir direcciones en la memoria.
  • Las direcciones descritas son todas direcciones virtuales.

El pseudocódigo de mm_struct es el siguiente:

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

Nota: Dado que el espacio de direcciones del proceso es una dirección de memoria descrita por direcciones virtuales lineales continuas, cada área de la memoria se puede distinguir por la dirección inicial y la dirección final. Como se muestra abajo:

imagen-20230826134746803

Aunque el espacio de direcciones del proceso describe una dirección virtual, el proceso aún necesita encontrar sus propios datos y código en la dirección real en la memoria, por lo que el sistema operativo utiliza el mapeo para convertir la dirección virtual en una dirección de memoria real. Durante el mapeo se utiliza una tabla de páginas, que registra el mapeo entre direcciones virtuales y direcciones de memoria reales, de la siguiente manera:

imagen-20230826135906135

Entendiendo la copia en escritura

Primero escriba el siguiente código para observar el fenómeno de copia en escritura:

#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 y ejecute el código anterior para ver el fenómeno:

imagen-20230826141508478

  • Después de que el proceso hijo modifica el valor de la variable val, el cambio en el valor val del proceso hijo no afecta el valor val del proceso padre.
  • Las direcciones val de los procesos padre e hijo son las mismas, pero los valores son diferentes.

Los procesos padre-hijo anteriores comparten la misma variable en el código. Cuando cualquiera de las partes intenta escribir, ambas partes utilizarán una copia, lo que se denomina copia en escritura.

En primer lugar, dado que todas las direcciones en el espacio de direcciones del proceso son direcciones virtuales, los datos leídos por los procesos padre e hijo en la misma dirección parecen ser diferentes. Cuando se crea el proceso hijo, el espacio de direcciones del proceso y la tabla de páginas utilizadas se copian del proceso padre, de la siguiente manera:

imagen-20230826142401503

Cuando el proceso hijo modifica val, el sistema operativo volverá a abrir un espacio para que el proceso hijo registre el valor modificado y luego modificará la dirección real asignada en la tabla de páginas para implementar la copia en escritura, de la siguiente manera:

imagen-20230826142642452

¿Por qué hay un espacio de direcciones de proceso?

Para comprender por qué existe un espacio de direcciones de proceso, primero debemos comprender dos cosas:

La esencia de malloc

Dado que los recursos de memoria son limitados, para reducir el desperdicio de espacio de memoria, el sistema operativo solo completa la dirección en la dirección virtual de la tabla de páginas cuando solicita memoria con malloc, y la dirección de memoria real en la tabla de páginas está vacía Mientras espera que el proceso lo use, asigne un espacio y complete la dirección real en la tabla de páginas. Esto evita el desperdicio de espacio causado cuando un proceso solicita espacio pero no lo utiliza.

El espacio de direcciones del programa ejecutable.

Cuando se compila el código fuente, el código y los datos se compilan de acuerdo con el método de direccionamiento correspondiente que se ha programado en el espacio de direcciones virtuales.

En sistemas Linux, puede utilizar objdumop -S 可执行程序名la dirección virtual del programa para ver:

imagen-20230826155041035

Después de que el proceso comienza a ejecutarse, la CPU primero ejecuta la dirección de entrada virtual, que también contiene la dirección. La CPU comenzará a saltar la tabla de páginas a través del contenido registrado en la dirección de entrada y luego ejecutará el código y los datos del proceso normalmente. .

¿Por qué hay un espacio de direcciones de proceso?

Primero, necesitamos saber cómo funciona el sistema operativo si no hay espacio de direcciones de proceso. Cuando no hay espacio de direcciones de proceso, no habrá tabla de páginas. Una vez que el proceso se carga en la memoria, la CPU lo ejecuta en el orden del código dentro del proceso. como sigue:

imagen-20230826150931606

  • Primero, en este caso, al ejecutar el código del proceso, si hay un problema con el código y se produce una operación de acceso a la memoria con un puntero salvaje, la CPU también realizará una operación de acceso incorrecta. Con el espacio de direcciones del proceso, también hay una tabla de páginas. Al acceder a cualquier dato, se debe mapear a través de la tabla de páginas. La tabla de páginas no solo almacena la relación de mapeo de la dirección, sino que también almacena la dirección de lectura de una determinada dirección. .Permisos de escritura, etc., si se utiliza un puntero comodín, la tabla de páginas lo interceptará.
  • En segundo lugar, en este caso, si el proceso quiere particionar los datos según el área global, el área estática y otras particiones, debe encontrar la dirección real del bloque completo en la memoria física para la partición, de modo que la gestión del proceso y la Gestión de la memoria Se requiere trabajo colaborativo. Pero con el espacio de direcciones del proceso y la tabla de páginas, el proceso solo necesita saber si las direcciones en el espacio de direcciones del proceso se pueden dividir según regiones, y la memoria física solo necesita encontrar el espacio, sin importar dónde se encuentre en la memoria. , porque al final Todos los accesos a datos se asignan a través de tablas de páginas y la misma gestión de procesos y gestión de memoria están desacopladas.
  • En tercer lugar, en este caso el código y los datos deben distinguirse por separado. Con el espacio de direcciones del proceso y la tabla de páginas, un proceso solo necesita acceder al código y los datos a través del espacio de direcciones del proceso. En todos los espacios de direcciones del proceso, las direcciones de partición del código y los datos son las mismas, de modo que todos los procesos puedan ver La vista es lo mismo cuando se trata de su propio espacio de direcciones de proceso.

Resumir:

  1. Evite el acceso aleatorio a direcciones y proteja la memoria física y otros procesos.
  2. Desacoplar la gestión de procesos y la gestión de la memoria.
  3. Ofrezca a todos los procesos una vista unificada del código y los datos.

Supongo que te gusta

Origin blog.csdn.net/csdn_myhome/article/details/132522396
Recomendado
Clasificación