7
votes

Comment les variables sont partagées entre deux processus lorsque la fourche est impliquée

/*  In alarm.c, the first function, ding, simulates an alarm clock.  */

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

static int alarm_fired = 0;

void ding(int sig)
{
    alarm_fired = 1;
}

/*  In main, we tell the child process to wait for five seconds
    before sending a SIGALRM signal to its parent.  */

int main()
{
    pid_t pid;

    printf("alarm application starting\n");

    pid = fork();
    switch(pid) {
    case -1:
      /* Failure */
      perror("fork failed");
      exit(1);
    case 0:
      /* child */
        sleep(5);
        printf("getppid: %d\n", getppid());
        kill(getppid(), SIGALRM);
        exit(0);
    }

/*  The parent process arranges to catch SIGALRM with a call to signal
    and then waits for the inevitable.  */

    printf("waiting for alarm to go off\n");
    (void) signal(SIGALRM, ding);

    printf("pid: %d\n", getpid());
    pause();
    if (alarm_fired)
        printf("Ding!\n");

    printf("done\n");
    exit(0);
}

I have run the above code under Ubuntu 10.04 LTS

> user@ubuntu:~/Documents/./alarm
> alarm application starting
> waiting for alarm to go off
> pid: 3055
> getppid: 3055
> Ding!
> done
I have read the following statement from a book.
  It’s important to be clear about the
  difference between the fork system
  call and the creation of new threads.
  When a process executes a fork call, a
  new copy of the process is created
  with its own variables and its own
  PID. This new process is scheduled
  independently, and (in general)
  executes almost independently of the
  process that created it.
Question:
It seems to me that the variable alarm_fired is shared between the original process and the new created process.Is that correct?

0 commentaires

3 Réponses :


7
votes

non. Chaque processus obtient sa propre copie de la variable (et à peu près tout le reste). Si vous modifiez la variable dans un processus, il n'est changé que dans ce processus, non dans les deux. Chaque processus a son propre espace d'adresse.

Comparer celui-ci avec des threads, où toutes les threades partagent un seul espace d'adresse, une variation d'une variable dans un thread sera visible dans tous les autres threads (dans ce processus).

du linux Fourchette (2) MANPAGE:

Fork () crée un processus d'enfant qui diffère du processus parent uniquement dans son PID et de son PPID, et que les utilisations de ressources sont définies sur 0. Les serrures de fichier et les signaux en attente ne sont pas hérités.


1 commentaires

@pls Voir mes commentaires sous Javier.



2
votes

Il est partagé dans le sens où immédiatement après la fourche, elle a la même valeur dans les deux processus. Mais lorsqu'il l'écrit soit, le changement n'est pas propagé à l'autre processus (que quels sont les différents.

Aussi, voir Copier sur Ecrire pour des trucs intéressants.

Edit

Il semble que le nouveau processus créé modifié la variable alarm_fired qui est alors vu plus tard par l'ancien processus

L'enfant est envoyer un signal au parent. Le parent exécute ensuite le gestionnaire et personnellement ensembles alarm_fired sur un. L'enfant lui-même ne touche jamais cette variable.


2 commentaires

@pls Voir mes commentaires sous Javier.


@ Q0987 Vous ne pouvez pas savoir quand le parent reçoit le signal (vous ne savez même pas qui fonctionne d'abord après la fourche). Une chose est claire: alarm_fired = 1; est exécuté par le gestionnaire. Le processus parent est le seul exécutant le gestionnaire.



1
votes

Non, les variables ne sont pas partagées sur un Fourche () . Dans votre code, le processus enfant ne touche jamais alarm_fired . Ce que l'enfant fait est envoyé un signal au parent. Ce signal incendie un gestionnaire de signal dans le contexte du processus parent, définissant la variable.


2 commentaires

La pause entraîne simplement la suspension du programme jusqu'à ce qu'un signal se produise. Lorsque le second processus envoie le signal, le processus d'origine le reçoit et appelle immédiatement la fonction Ding qui change la valeur d'alarm_fired. Est-il vrai que la fonction Ding intercepte le signal tôt que la pause?


Ding () Ne intercepte pas le signal, c'est le gestionnaire de signal. Cela signifie que le processus parent l'appellera à la suite de la réception du signal. Pause () Les retours après que tout le traitement du signal ait eu lieu, cela signifie appeler des gestionnaires.