2011-03-19 13 views
14

Esto es sobre C en Linux.Horquilla - ¿mismas direcciones de memoria?

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 algo de valor en eso. Luego imprimo la dirección de esta variable con printf("%p",&x).

Ambos procesos imprimen la MISMA dirección. Pensé que cada niño recibe 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?

Respuesta

20

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 espacio de direcciones virtuales 4G y los administradores de sistemas operativos y de memoria de hardware asignan sus direcciones virtuales a físicas.

Por lo tanto, si bien puede parecer que dos procesos tienen la misma dirección para una variable, esto es sólo el virtual de direcciones.

El administrador de memoria trazará un mapa de eso a una totalmente diferente física dirección un.

Esta asignación también es lo que le permite ejecutar diez procesos, cada uno ocupando 1G, aunque su máquina solo tenga 4G de memoria física. El sistema operativo puede intercambiar partes de su memoria en el disco y volverlas a poner cuando intente usarlas.


un: Parcialmente, esto es cierto. Se puede asignar 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.

+9

En realidad, se correlacionará con las mismas direcciones físicas hasta que se produzca la copia por escritura. –

+0

Gracias, lo entiendo ahora. – Asheron2332

+0

@R, afirmaré que como parte del bit "y así sucesivamente" al final :-) – paxdiablo

2

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.

5

Si se detiene a pensar por un minuto, sería imposible para fork dar a las variables direcciones separadas en el proceso primario y secundario. Ya podría haber almacenado las direcciones en cualquier lugar de la memoria, o haberlas generado en hash, o haberlas guardado en un archivo, o cualquier otra cosa, y cualquier cosa en el elemento secundario que dependiera de que estas direcciones fueran válidas se rompería horriblemente. De hecho, forkhace y debe crear un proceso secundario en el que el espacio de direcciones virtuales sea idéntico al espacio de direcciones virtuales del elemento primario.

+0

Supongo que los efectos secundarios mensurables de la horquilla no son en realidad parte del espacio de direcciones virtuales en el momento de la horquilla. – Neil

+0

"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 compleja de datos que utiliza el puntero en la memoria debe mantenerse intacta. –

+0

@Ben: No si se recargó en el mismo proceso o un descendiente bifurcado del mismo proceso que no ha llamado 'exec'. –

1

Para entender cómo puede suceder esto, debe comprender el proceso/modelo de subprocesos 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 hilo y el proceso de Windows.

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

Cuando se genera el proceso en el entorno de Windows, el sistema operativo construye un espacio de direcciones totalmente nuevo desde cero y lo rellena por 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 esto será muy baja. E incluso en el caso en que ambas variables usen la misma dirección, estas dos variables seguirán siendo objetos diferentes.

Los procesos de UNIX tienen similitud con los subprocesos y con los procesos de Windows. Al igual que en el segundo caso, OS creará NUEVO espacio de direcciones para un proceso secundario, pero a diferencia de Windows, Linux lo crea mediante la copia diferida del espacio de direcciones del proceso principal con el uso del enfoque Copiar-Escribir-Escribir (COW). VACA 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 volverá a estar involucrado para copiar el fragmento de memoria que se va a 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 él.

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 espacios de direcciones diferentes. Luego has ejecutado el mismo código en ambos hijos. En otras palabras, tiene el mismo estado inicial del diseño de 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.

0

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 primario y secundario), su dirección será la misma hasta que no actualice su valor. si un proceso actualiza el valor de la variable global, entonces ese proceso tendrá una copia única del mismo (a través de la copia en el mecanismo de escritura).

+0

¿Hay algún motivo por el que publique una pregunta de 3.5 años? Intenta evitar las respuestas "Yo también". –

Cuestiones relacionadas