fork() y memoria compartida en b/n procesos creados usándolo

Requisito previo: fork( ) en C. Entonces, cuando hacemos un fork(), ¿cuáles son las secciones que comparten los dos procesos? ¿La memoria del montón es por proceso? ¿Son compartidas las variables globales? ¿Malloc devolverá la misma dirección a ambos? Ejecutemos el siguiente programa y observemos su salida para aclarar las preguntas anteriores. 

C

// C program to demonstrate working of fork()
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/mman.h>
 
int globalVar; /* A global variable*/
 
int main(void)
{
  int localVar = 0;
  int* p = (int*) mmap(NULL, sizeof (int) , PROT_READ | PROT_WRITE,
                    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  pid_t childPID = fork();
 
  // Putting value at allocated address
  *p = 0;
 
  if (childPID >= 0) // fork was successful
  {
    if (childPID == 0) // child process
    {
     // sleep (1);
      printf("\n Child Process Initial Value :: localVar"
        " = %d, globalVar = %d", localVar,
        globalVar);
      localVar++;
      globalVar++;
 
     // int c = 500;
      printf("\n Child Process :: localVar = %d, "
        "globalVar = %d", localVar, globalVar);
      printf("\n Address of malloced mem child = %p "
        "and value is %d", p, *p);
      printf("\n lets change the value pointed my malloc");
 
      *p = 50;
      printf("\n Address of malloced mem child = %p "
        "and value is %d", p, *p);
      printf("\n lets change the value pointed my "
        "malloc in child");
 
      *p = 200;
      printf("\n Address of malloced mem child = %p "
        "and value is %d\n\n\n", p, *p);
            exit(EXIT_SUCCESS);
    } else {
        wait(NULL);
     // sleep(1);
      printf("\n Parent process Initial Value :: "
        "localVar = %d, globalVar = %d",
        localVar, globalVar);
 
      localVar = 10;
      globalVar = 20;
      printf("\n Parent process :: localVar = %d,"
        " globalVar = %d", localVar, globalVar);
      printf("\n Address of malloced mem parent= %p "
        "and value is %d", p, *p);
 
    //  *p = 100;
      printf("\n Address of malloced mem parent= %p "
        "and value is %d", p, *p);
      printf("\n lets change the value pointed my"
          " malloc in child");
     // *p = 400;
      printf("\n Address of malloced mem child = %p"
        " and value is %d \n", p, *p);
    }
  }
  else // fork failed
  {
    printf("\n Fork failed, quitting!!!!!!\n");
    return 1;
  }
 
  return 0;
}
 Parent process Initial Value :: localVar = 0, globalVar = 0
 Parent process :: localVar = 10, globalVar = 20
 Address of malloced mem parent= 0x1bb5010 and value is 0
 Address of malloced mem parent= 0x1bb5010 and value is 100
 lets change the value pointed my malloc in child
 Address of malloced mem child = 0x1bb5010 and value is 400 

 Child Process Initial Value :: localVar = 0, globalVar = 0
 Child Process :: localVar = 1, globalVar = 1
 Address of malloced mem child = 0x1bb5010 and value is 0
 lets change the value pointed my malloc
 Address of malloced mem child = 0x1bb5010 and value is 50
 lets change the value pointed my malloc in child
 Address of malloced mem child = 0x1bb5010 and value is 200

Explicación ::

  1. Por lo tanto, cada proceso secundario y principal tienen su propia copia de variable global y localvar; de lo contrario, si la hubieran compartido, habríamos obtenido «Valor inicial del proceso secundario::localVar = [10], variable global [20]» en el proceso secundario que se asignó en el proceso principal que se ejecutó primero pero nosotros no.
  2. Aunque la dirección de la memoria devuelta por malloc es la misma, pero en realidad apuntan o se asignan a una dirección física diferente, de lo contrario, cuando el padre asignó el valor de 100 en la dirección de memoria 0x1535010, los mismos 100 que deberíamos haber obtenido en el niño, pero obtuvimos 0.
  3. Una forma de asignar memoria para ser compartida entre procesos es usando la función mmap. Además de eso, para garantizar que el proceso principal acceda al valor modificado realizado por el proceso secundario, el programa necesita un punto de sincronización. esto se puede hacer usando la función esperar (NULL). Con esto, el proceso principal espera que el proceso secundario haya terminado para continuar. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *