Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1679 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] fork() - étudier la mémoire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] fork() - étudier la mémoire

n°933428
nodus
Posté le 29-12-2004 à 10:02:36  profilanswer
 

J'aimerais voir un peu comment se fait la gestion de la mémoire lors d'un fork(). On m'a dit qu'aprés le fork le processus fils partage les zones mémoires du père tant que l'un de deux ne la modifie pas. Dans le cas d'une modification le fils créérais une zone propre à lui-même. Pour cela j'ai écris un petit programme.  
 
Le problème est qu'il est bien trop rapide lorsque j'essaie de visualiser son exécution avec top (sous linux), est-ce qu'avec gdb j'arriverais à mieux voir le phénomène ?
 
Voici le prog:
 

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #define SIZE 1024*1024*10
  5. int
  6. main (void)
  7. {
  8.   char *ptr = NULL;
  9.   long long i;
  10.   long long j;
  11.   ptr = malloc (sizeof (char) * SIZE);
  12.   for (i = 0; i < SIZE; i++)
  13.     ptr[i] = 0;
  14.   if (!fork ())
  15.     {
  16.       i = 0;
  17.       for (i = 0; i < SIZE; i++)
  18. {
  19.   for (j = 0; j < 2000; j++)
  20.     {
  21.       j++;
  22.       j--;
  23.     }
  24.   ptr[i] = 1;
  25. }
  26.       printf ("done\n" );
  27.     }
  28.   while (1);
  29. }


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
mood
Publicité
Posté le 29-12-2004 à 10:02:36  profilanswer
 

n°933460
Truk
Posté le 29-12-2004 à 11:13:01  profilanswer
 

avec gdb tu va faire du pas a pas. Tu vas voir chaque passage dans tes boucles for.
 
j'ai pas verifie mais je ne sais pas comment il se comporte notre ami gdb dans un prg multi process.
C'est sur que tu peux regarder les valeurs des variables et avoir leur implantation memoire (virtuelle ?) mais au dela de ca.. auras tu le pid ?
 
j'ai toujours eu en tete qu'a l'exec du fork le processus fils a son propre espace memoire virtuelle qui est une copie du contexte du parent.
Il connait les descripteurs ke le parent connait, variables, etc.
Mais les deux espaces memoire virtuelle des processus sont distincts physiquement.
 
Ca me parait d'ailleurs logique puisque suivant que l'ordonnanceur donne la main au fils ou au pere le retour du fork est different.
 
Enfin, la fonction fork est kan meme sencee dupliquer le process. C d'ailleurs explicite par le cas d'erreur possible en sortie :
 

Code :
  1. #include <errno.h>
  2. ...
  3. pid_t result;
  4. result = fork();
  5. if(errno==EAGAIN) printf("Memoire insuff pour dupliquer le processus\n" );
  6. /* Mais la memoire peut se liberer, il faut donc recommencer le fork... utiliser un do/while par exemple */


 
j'espere avoir repondu a ta question.. meme si ce n'est pas sur cette voie que tu cherchais.


Message édité par Truk le 29-12-2004 à 11:14:13
n°933523
darkoli
Le Petit Dinosaure Bleu
Posté le 29-12-2004 à 12:51:22  profilanswer
 

Au moment où le fork est fait, seule une petite partie de la mémoire est dupliquée. En fait la gestion de la mémoire fonctionne par bloc et dés qu'un bloc est différent pour les deux processus il est dupliqué mais tant que le bloc est identique pour les deux processus il ne sera pas dupliqué.
 
Donc tant qu'il n'est pas nécessaire de dupliquer une zone mémoire elle ne le sera pas.
 
J'espère ne pas avoir dit trop de conneries.
 


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
n°933524
darkoli
Le Petit Dinosaure Bleu
Posté le 29-12-2004 à 12:53:08  profilanswer
 

Sinon "man fork" explique bien ce qu'il se passe :

FORK(2)                                            Manuel du programmeur Linux                                           FORK(2)
 
NOM
       fork - Créer un processus fils.
 
SYNOPSIS
       #include <sys/types.h>
       #include <unistd.h>
 
       pid_t fork(void);
 
DESCRIPTION
       fork  crée  un  processus  fils qui diffère du processus parent uniquement par ses valeurs PID et PPID et par le fait que
       toutes les statistiques d’utilisation des ressources sont remises à zéro. Les verrouillages de fichiers, et  les  signaux
       en attente ne sont pas hérités.
 
       Sous  Linux,  fork  est implementé en utilisant une méthode de copie à l’écriture.  Ceci consiste à ne faire la véritable
       duplication d’une page mémoire que lorsqu’un processus en modifie une instance. Tant qu’aucun des deux processus  n’écrit
       dans  une  page  donnée, celle‐ci n’est pas vraiment dupliquée.  Ainsi les seules pénalisations induites par fork sont le
       temps et la mémoire nécessaires à la copie de la table des pages du parent ainsi que la création d’une structure de tâche
       pour le fils.
 
VALEUR RENVOYÉE
       En  cas  de succès, le PID du fils est renvoyé au processus parent, et 0 est renvoyé au processus fils. En cas d’échec -1
       est renvoyé dans le contexte du parent, aucun processus fils n’est créé, et errno contient le code d’erreur.
 
ERREURS
       EAGAIN fork ne peut pas allouer assez de mémoire pour copier la table des pages du père et une structure de tâche pour le
              fils.
 
       ENOMEM fork a échoué car le noyau n’a plus assez de mémoire.
EXEMPLE
           pid_t   pid;
 
           pid = fork ();
 
           if (pid > 0) {
                /* Processus père      */
           } else if (pid == 0) {
                /* Processus fils      */
           } else {
                /* Traitement d’erreur */
           }
 
CONFORMITÉ
       L’appel‐système fork est conforme à SVr4, SVID, POSIX, X/OPEN, BSD 4.3.
 
VOIR AUSSI
       clone(2), execve(2), vfork(2), wait(2).
 
TRADUCTION
       Christophe Blaess, 1996‐2003.
 
LDP                                                      18 juillet 2003                                                 FORK(2)


---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
n°933555
nodus
Posté le 29-12-2004 à 14:06:04  profilanswer
 

Mais comment pouvoir observer visuellement ce phénomène ?


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
n°933855
nodus
Posté le 29-12-2004 à 21:29:25  profilanswer
 

Personne n'a d'idée  :??:


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
n°933860
kadreg
profil: Utilisateur
Posté le 29-12-2004 à 21:33:41  profilanswer
 

averc un sleep.  
 
Le processus père crée un grand tableau (plusieurs pagesà qu'il rempli. On va voir sa mémoire monter.
 
Puis il forke, le fils va faire des modifications au fur et à mesure dans le grand tableau au hasard (avec un sleep entre chaque écriture pour laisser le temps de voir), et chaques fois qu'il écrit dans une page ou il n'a pas encore écrit, sa mémoire prise augmente.
 
Par contre, je me souviens plus de la taille d'une page mémoire sous linux. Il me semble qu'elle fait 4ko ou 4Mo, suivant le système d'addressage utilisé.  
 


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
n°933917
nodus
Posté le 30-12-2004 à 00:08:39  profilanswer
 

Elle est de 4ko sur processeur 32bit et 8ko sur 64bit :jap:


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
n°933944
bjone
Insert booze to continue
Posté le 30-12-2004 à 03:59:35  profilanswer
 

4Ko en standard, 4Mo en mode PAE pour les x86, mais à vérifier si en PAE on le choix ou pas.
 
je crois qu'en x86-64 les pages font 4Mo.

n°933945
bjone
Insert booze to continue
Posté le 30-12-2004 à 04:00:22  profilanswer
 

nodus >> tu parles du x68-64, ou des PowerPC par exemple ?
 
(je peux être complètement à coté de la plaque)

mood
Publicité
Posté le 30-12-2004 à 04:00:22  profilanswer
 

n°934112
nodus
Posté le 30-12-2004 à 14:37:22  profilanswer
 

Pour le 8ko c'est sur des sparcs, j'imagine que ça doit être pareil sur les autres architectures 64bit.


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
n°934152
Lam's
Profil: bas.
Posté le 30-12-2004 à 15:11:56  profilanswer
 

H.S.
Sous HP-UX, chaque programme peut avoir une valeur différente, entre 4K et 256M (ça c'est de la page!) avec ça:
http://docs.hp.com/en/B2355-90689/chatr.1.html

n°934189
bjone
Insert booze to continue
Posté le 30-12-2004 à 15:49:39  profilanswer
 

Lam's a écrit :

H.S.
Sous HP-UX, chaque programme peut avoir une valeur différente, entre 4K et 256M (ça c'est de la page!) avec ça:
http://docs.hp.com/en/B2355-90689/chatr.1.html


 
oui & non, c'est sur une machine en PA-RISC, ou un Itanium (qui est je crois compatible naturellement avec les binaires PA-RISC).
 
la taille des pages est complétement dépendantes des capacitées du MMU du CPU. ie ce n'est pas une caractéristique propre à un OS.


Message édité par bjone le 30-12-2004 à 15:50:12
n°934194
bjone
Insert booze to continue
Posté le 30-12-2004 à 15:54:22  profilanswer
 

autant pour moi, en x86-64 même en long mode, les pages restent à 4Ko:
http://lwn.net/2001/features/OLS/pdf/pdf/x86-64.pdf

n°934199
Lam's
Profil: bas.
Posté le 30-12-2004 à 15:59:33  profilanswer
 

bjone a écrit :

oui & non, c'est sur une machine en PA-RISC, ou un Itanium (qui est je crois compatible naturellement avec les binaires PA-RISC).
 
la taille des pages est complétement dépendantes des capacitées du MMU du CPU. ie ce n'est pas une caractéristique propre à un OS.


D'une part, c'est effectivement sur PA-RIC.
 
D'autre part, effectivement, sur x86 c'est soit 4K soit 4M. L'itanium tourne à 16K, mais il faudrait que je vérifie (j'ai tendance à me mélanger les pinceaux entre la segmentation et le paging).
 
 

n°934326
matafan
Posté le 30-12-2004 à 18:43:51  profilanswer
 

Et sur architecture Power, les pages font 4kB ou 16MB, au choix. Et bientot il y aura des pages de 16kB et 16GB.

n°934351
bjone
Insert booze to continue
Posté le 30-12-2004 à 19:18:13  profilanswer
 

16Go de page ? mmm.... c'est voir à très long terme :D (ou alors pour du mapping d'espace de périph)

n°934364
nodus
Posté le 30-12-2004 à 19:50:05  profilanswer
 

Par contre en ayant exécuté mon programme j'ai remarqué que le printf n'était pas exécuté, c'est normal selon vous :??:


---------------
Et toi, tu crois que les ours polaires vont chier dans les bois ?
n°979620
djmalo
Posté le 12-02-2005 à 19:38:10  profilanswer
 

darkoli a écrit :

Au moment où le fork est fait, seule une petite partie de la mémoire est dupliquée. En fait la gestion de la mémoire fonctionne par bloc et dés qu'un bloc est différent pour les deux processus il est dupliqué mais tant que le bloc est identique pour les deux processus il ne sera pas dupliqué.
 
Donc tant qu'il n'est pas nécessaire de dupliquer une zone mémoire elle ne le sera pas.
 
J'espère ne pas avoir dit trop de conneries.


 
Donc si je comprends bien :
 
Mettons que j'initialise un grand tableau de milliers d'entrées.
Je fais un fork. Le processus fils ne fera que consulter ce tableau, jamais il n'écrira dedans. Conclusion : le tableau ne sera pas dupliqué et sera simplement partagé entre les 2 processus ce qui évite un grand gaspillage de mémoire?
 
Si oui ç'est très intéressant, car je comptais utiliser une shared memory pour éviter la duplication du tableau. Mais comme il n'est pas dupliqué, pas besoin d'avoir recours à ce genre d'astuce.
 
J'ai bien tout compris? :)


Message édité par djmalo le 12-02-2005 à 19:38:47
n°979642
bjone
Insert booze to continue
Posté le 12-02-2005 à 20:17:53  profilanswer
 

tout à fait mon colonel...
 
sauf que si le processus père écrit dans le tableau (dumoins l'espace alloué), le fils verra toujours les anciennes données.
 
donc si tu veux que le père produise, et le fils consomme, ça marchera pas.

n°982784
moi23372
Posté le 15-02-2005 à 21:38:46  profilanswer
 

Il me semble que des erreurs on été dite...
 
D'après ce que je sais et ce que j'ai expérimenté sur cette fonction
 
fork() creer donc un processus identique à celui du pere...
Le fils hérite des fichiers ouverts, mais n'a pas la même zone mémoire alouée, ce qu'il fait qu'il n'ont aucune zone mémoire commune...
Pour faire communiqué deux processus ayant un lien de parenté, il existe les ipc
 
=> les pipes
=> les files de messages
=> les sémaphores (pour la synchronisation)
=> les mémoires partagées (shared memory)
=> connexion par réseau  
 
chaque processus à donc son propre SEGMENT de DONNEE, SEGMENT de PILE et SEGMENT de CODE (DS, SS et CS)...
 
donc je suis kazi certain à 99% qu'au départ, le fils n'aura pas accès aux zone mémoire du père puisque ce n'est pas la même zone mémoire qui lui ait allouée...  
j'ai eu l'occasion de testé cela il y a deux mois de ça sur une grosse application UNIX que j'ai du faire...
Donc si tu veux vraiment faire communiqué les deux processus, je te conseille la mémoire partagée, voir les files de messages...


Message édité par moi23372 le 15-02-2005 à 21:41:14
n°982797
manatane
En vous remerciant, bonsoir
Posté le 15-02-2005 à 21:45:20  profilanswer
 

Merci pour ces lumières mais en fait pour des questions d'optimisation, la plupart des implémentations ne procédent pas à une copie compléte des données/pile/tas du père sachant qu'un fork est souvant suivi par un exec. Elles utilisent à la place une technique appelée copy-on-write (COW) : elles sont partagées par le père et le fils et ce n'est que quand l'un des 2 tente de modifier l'une de ces régions que le noyau fait une copie de cette région seulement.
Et si tu fais un vfork là le fils fonctionne dans l'espace d'adressage du père, c'est super rigolo.


Message édité par manatane le 15-02-2005 à 21:46:44
n°983964
moi23372
Posté le 16-02-2005 à 20:41:57  profilanswer
 

ah tiens si j'avais su ça avant je crois que ça m'aurais facilité pas mal de truc pour l'examen...

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] fork() - étudier la mémoire

 

Sujets relatifs
Espace mémoire saturé[C] problème avec libération de la mémoire
Comment fonctionne la memoire ?extension php en C (gestion de la mémoire)
thread mutex et mémoire partagéeerreur avec la fonction system => unable to fork....
[Class] Constructeur et allocation de mémoire.[ Defunct ] Comment éviter les zombies après un *fork -> execl*
problème désallocation mémoire (résolu)Taille mémoire des énumérations
Plus de sujets relatifs à : [C] fork() - étudier la mémoire


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR