2009-08-10 8 views
1

Je possède ce programme en C++ qui bifurque deux nouveaux procédés:A propos de l'appel système fork et les variables globales

#include <pthread.h> 
#include <iostream> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <cstdlib> 
using namespace std; 

int shared; 

void func(){ 
    extern int shared; 
    for (int i=0; i<10;i++) 
     shared++; 
    cout<<"Process "<<getpid()<<", shared " 
     <<shared<<", &shared " 
     <<&shared<<endl; 
} 

int main(){ 
    extern int shared; 
    pid_t p1,p2; 
    int status; 
    shared=0; 
    if ((p1=fork())==0) {func();exit(0);}; 
    if ((p2=fork())==0) {func();exit(0);}; 
    for(int i=0;i<10;i++) 
     shared++; 
    waitpid(p1,&status,0); 
    waitpid(p2,&status,0);; 
    cout<<"shared variable is: "<<shared<<endl; 
    cout<<"Process "<<getpid()<<", shared " 
     <<shared<<", &shared " 
     <<&shared<<endl; 
} 

Les deux processus fourchus font un incrément sur les variables partagées et le processus parent fait la même chose. Comme la variable appartient au segment de données de chaque processus, la valeur finale est 10 car l'incrément est indépendant.

Cependant, l'adresse mémoire des variables partagées est la même, vous pouvez essayer de compiler et de regarder la sortie du programme. Comment cela peut-il être expliqué? Je ne peux pas comprendre cela, je pensais que je savais comment fonctionne fork(), mais cela semble très étrange ..

J'ai besoin d'une explication sur la raison pour laquelle l'adresse est la même, même si elles sont des variables distinctes.

+0

Rappelez-vous que fork fait une copie à l'écriture, donc jusqu'à ce que vous changiez la var c'est la même chose dans tous les processus – Lodle

+0

Il ne peut pas fonctionner autrement, sinon vos pointeurs seraient invalidés après fourchette. Pas très utile ... – Eugene

Répondre

9

Le système d'exploitation utilise virtual memory et des techniques similaires pour s'assurer que chaque processus voit différentes cellules de mémoire (virtuelles ou lues) aux mêmes adresses; seule la mémoire explicitement partagée (par exemple via shm) est partagée, toute la mémoire par défaut est séparée parmi des processus distincts.

4

Les pointeurs sur les systèmes modernes ne correspondent pas aux adresses de mémoire matérielles réelles. Les adresses correspondent plutôt à un espace virtuel géré par le système d'exploitation. Par conséquent, les adresses de pointeur pour deux processus différents peuvent sembler être les mêmes quand elles ne le sont pas en réalité.

7

Ceci est appelé "adresse virtuelle". Chaque processus a son propre espace d'adressage, et chaque adresse signifie quelque chose de différent, selon le processus. fork() crée une copie, au lieu de partager des données (techniquement, ils peuvent obtenir une copie sur écriture partagée, mais cela a le même effet que la copie initiale). IOW, la variable "shared" n'est pas partagée entre les processus.

0

Cela s'applique également aux objets pthread_mutex. Dites que j'ai mutex dans le parent qui est verrouillé et déverrouillé dans une fonction particulière. Maintenant, le parent crée un processus enfant. Le parent et l'enfant peuvent appeler cette fonction simultanément (le parent n'est pas vraiment bloqué jusqu'à ce que l'enfant se termine comme parent est un programme multi-thread, le thread qui engendre l'enfant est seulement un bloqué). L'état de l'objet mutex est-il partagé entre les deux processus? Si dans parent, mutex a été verrouillé alors l'enfant a été créé enfant arrive à courir premier enfant voit le mutex dans l'état verrouillé comme il vient d'hériter l'objet mutex comme il est de parent maintenant enfant déverrouille mutex Comment est le état de ce mutex dans le parent maintenant - toujours verrouillé (parce que le parent n'a jamais déverrouillé) ou Déverrouillé parce que l'enfant l'a déverrouillé.

Est-il correct d'appeler une telle fonction qui verrouille/déverrouille les mutex globaux du parent et de l'enfant?

0

oui ce que vous pensiez juste mais pour économiser de la mémoire, en interne les pages sont partagées entre le parent et l'enfant jusqu'à ce que l'enfant exécute l'appel système exec ou modifie l'une des variables ou structures de données. les pages sont partagées entre parent et enfant ..... si la page est modifiée par l'enfant, alors cette page sera copiée dans une zone de mémoire séparée et sera assignée à child.if si elle est modifiée par parent, alors cette page sera copiée pour séparer la zone de mémoire et affecté au parent

Questions connexes