Bifurcación: ¿las mismas direcciones de memoria?

6 minutos de lectura

avatar de usuario
Asheron2332

Se trata de C en Linux.

tengo fork() en main() donde creo 2 procesos secundarios. Luego, en ambos procesos secundarios, ejecute la función abc()donde hay una variable local x. Escribo algún valor en él. Luego imprimo la dirección de esta variable con printf("%p",&x).

Ambos procesos imprimen la MISMA dirección. Pensé que cada niño obtiene una copia (independiente) de la memoria de los padres. Necesito que cada proceso tenga su propia variable. x. ¿Cómo puedo hacer eso o estoy haciendo algo mal?

Debe comprender que existe una desconexión entre la memoria física y el espacio de direcciones virtuales de un proceso.

Cada proceso individual obtiene su propio El espacio de direcciones virtuales 4G y es el trabajo de los sistemas operativos y los administradores de memoria de hardware para mapear sus direcciones virtuales a las físicas.

Entonces, si bien puede parecer que dos procesos tienen la misma dirección para una variable, esa es solo la virtual habla a.

El administrador de memoria mapeará eso en un lugar totalmente diferente. físico habla aa.

Esta asignación también es lo que le permite ejecutar diez procesos, cada uno de los cuales ocupa 1 G, aunque su máquina solo tenga 4 G de memoria física. El sistema operativo puede intercambiar bits de su memoria en el disco y recuperarlos cuando intente usarlos.


a: Sobre todo, esto es cierto. Puede asignarse a la misma dirección física si está compartiendo cosas entre procesos. Por ejemplo, memoria compartida, código y datos del núcleo, bibliotecas dinámicas, etc.

  • En realidad, todo se asignará a las mismas direcciones físicas hasta que se produzca la copia en escritura.

    – R.. GitHub DEJA DE AYUDAR A ICE

    19 de marzo de 2011 a las 23:36

  • Gracias, ahora lo entiendo.

    – Asheron2332

    20 de marzo de 2011 a las 0:08

  • @R, lo diré como parte del bit “y así sucesivamente” al final 🙂

    – pax diablo

    20 de marzo de 2011 a las 2:16

  • @paxdiablo ¿Hay alguna forma de imprimir las direcciones físicas de ambas variables?

    – javadr

    3 de enero de 2018 a las 15:05

Si te detienes a pensar por un minuto, sería imposible que fork para dar a las variables direcciones separadas en el proceso padre e hijo. Ya podrías haber almacenado las direcciones en cualquier lugar de la memoria, o haberlas cifrado, o guardado en un archivo, o cualquier cosa, y luego cualquier cosa en el niño que dependiera de que estas direcciones fueran válidas se rompería horriblemente. De hecho fork lo hace y deber cree un proceso secundario en el que el espacio de direcciones virtuales sea idéntico al espacio de direcciones virtuales del padre.

  • Supongo que los efectos secundarios medibles de la bifurcación no son en realidad parte del espacio de direcciones virtuales en el momento de la bifurcación.

    – Neil

    19 de marzo de 2011 a las 23:39

  • Las “direcciones guardadas en un archivo” se pueden romper si se cargan en un nuevo proceso (en general), por lo que no es una restricción para fork. Pero la estructura de datos compleja que utiliza punteros en la memoria debe mantenerse intacta.

    – Ben Voigt

    20 de marzo de 2011 a las 0:15

  • @Ben: no si se vuelve a cargar en el mismo proceso o en un descendiente bifurcado del mismo proceso que no ha llamado exec.

    – R.. GitHub DEJA DE AYUDAR A ICE

    20 de marzo de 2011 a las 0:45

  • @R: Lo vería como una consecuencia de cómo fork funciona, no la razón fork funciona como lo hace.

    – Ben Voigt

    20 de marzo de 2011 a las 0:50

Debido al sistema de memoria virtual, cada proceso secundario tiene su propia variable con la misma dirección (virtual).

Las mismas direcciones virtuales no apuntarán a la misma ubicación física.

Para comprender cómo puede suceder esto, debe comprender el modelo de proceso/hilo de Linux. Linux sigue el modelo fork-and-exec heredado de UNIX. El proceso generado por la llamada al sistema fork() en este modelo es una especie de cruce entre el proceso de Windows y el subproceso.

Cuando se genera el subproceso (no importa en Linux o en Windows), el nuevo subproceso comparte su espacio de direcciones con el principal. Ambos pueden encontrar los mismos objetos accediendo a las mismas direcciones. Pero estos hilos usan pilas diferentes. Como resultado, se garantiza que las variables locales de ambos subprocesos no tendrán las mismas direcciones.

Cuando el proceso se genera en el entorno de Windows, el sistema operativo crea un espacio de direcciones completamente nuevo desde cero y lo llena con la memoria y los datos necesarios. En teoría, la variable local de ambos procesos puede tener las mismas direcciones, pero en la práctica la probabilidad de que esto suceda será muy baja. E incluso en el caso de que ambas variables usen la misma dirección, estas dos variables seguirán siendo objetos diferentes.

Los procesos de UNIX tienen similitud con los hilos y con los procesos de Windows. Como en el caso del segundo, el sistema operativo creará NUEVO espacio de direcciones para un proceso secundario, pero a diferencia de Windows, Linux lo crea mediante una copia diferida del espacio de direcciones del proceso principal con el uso del enfoque Copy-On-Write (COW). COW significa que ambos procesos compartirán la misma memoria, pero hasta el momento en que uno de ellos la modifique. En el momento del intento de escribir en la memoria, el sistema operativo estará nuevamente involucrado para hacer una copia de la parte de la memoria que se cambiará y asignará una copia al padre y otra al hijo. A partir de este momento, cada proceso funcionará con su propia copia independiente de los objetos en el fragmento de memoria modificado, pero seguirán teniendo las mismas direcciones. Lo mismo es cierto para la pila y las variables locales almacenadas en ella.

En su caso, tiene dos hijos con dos copias de la misma pila en las que las variables locales se almacenan en las mismas direcciones pero en diferentes espacios de direcciones. Entonces ha ejecutado el mismo código en ambos niños. En otras palabras, tiene el mismo estado inicial del diseño de la pila y ejecuta el mismo código que modifica este diseño de la misma manera. Como resultado, tendrá las mismas variables locales ubicadas en las mismas direcciones.

ya que está imprimiendo la dirección de la variable de pila (variable local). su dirección será la misma (no importa si actualiza su valor o no). ya que ambos procesos comparten una pila virtual común.

pero si está tratando de imprimir la dirección de una variable global dentro de la función común (llamada desde el proceso principal y secundario), entonces su dirección será la misma hasta el punto en que no actualice su valor. si un proceso actualiza el valor de la variable global, ese proceso tendrá una copia única (a través del mecanismo de copia en escritura).

  • ¿Hay alguna razón por la que está publicando una pregunta de hace 3,5 años? Intente evitar las respuestas “Yo también”.

    –David C. Rankin

    18 de diciembre de 2014 a las 5:42

  • ¿Hay alguna razón por la que está publicando una pregunta de hace 3,5 años? Intente evitar las respuestas “Yo también”.

    –David C. Rankin

    18 de diciembre de 2014 a las 5:42

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad