Skip to content

Processus Unix

Processus légé vs lourds

  • Processus léger : ne fait pas allouer un nouvelle espace mémoire
  • Processus lourd : fait allouer un nouvelle espace mémoire

fork : Syntaxe

pid_t fork(void);

Fonctionnement : Créer un clone du processus courant. Ce clone est un fils du processus courant. Quand on l'appel ou duplique l'espace mémoire pour le fils. Néanmoins les signaux réçu ne sont pas conserver.

Retour : En cas de succès 0 dans le fils, et PID du fils dans le père. En cas d'échec -1 et errno est mis à jour (dans le père seulement)

Exemple :

...

// Le père tourne
int pid = fork();

// Code du fils
if (pid == 0) {

    ...
}

// Si le le père continue ici
if (pid < 0) {

    ...
}

En fait si le pid vaux 0, alors c'est à dire qu'on est dans le processus fils. Après l'executiond de celui ci on check si il ya une erreur.

Apparté : Segments

Mémoire virtuelle :

  • T1: Text
  • D1: Données
  • H1: Tas (HEAP)
  • S1: Pile (STACK)
  • Sys: Système

Quand on fait un nouveau fils, on duplique tout dans la mémoire phyisque sauf :

  • T1: Text
  • Sys: Système

Quand on fait un thread on partage tout sauf la pile

Processus léger : Syntaxe

Arguments - Pid, Flags, pile

sys_clone_asm(pid, CLONE_VM|CLONE_FILE|CLONE_SIGAHND, (uchar*) malloc(SZ ...));
//                                                       ^^^^^^^^^^^^^
//                                               c'est le pointeur vers la pile qu'on lui attribut

// Code du fils
if (pid == 0) {

    ...
}

// Si le le père continue ici
if (pid < 0) {

    ...
}

Même fonctionnement que pour les processus lourds

Attente

// Permet d'attendre le changement de statu d'un fils et le met dans l'entier pointer.
pid_t wait(int* status)

// Permet d'attendre un PID spécifique en ajoutant un tag
pid_t wait_pid(-1, int* status, WUNTRACED|WCONTINUED)

Fonction : Attend une éveement sur un procesus fils. Et met sont statut dans l'entier pointer.

On peut décoder les valeurs du status grâce à des macro :

WIFEEXITED(status)
WIFESIGNALED(status)
WTERMSIGN(status)

// On les met dans des if( ... ) pour les utiliser.

Processus zombie

Les diférentes façons, pour un père de manager* la terminaison d'un fils sont :

  • Positionner le gestionnaire du signal SIGCHILD
  • Faire un wait ou waitpid qui renvoie le ID du fils.

Si le processus père meurt avant le processus fils -> Alors le processus enfant deviens adopter par le processus père du père

(le processus de base c'est le pid == 1 qui se nomme le porcessus init)

Exemple

int main (int arc, char* arv) {

    int stauts pid;

    pid=fork();

    if (pid==0) {

        write(1, "hel", 3);
        exit(O);
    }

    wait(&status);
    write(1,"lo\n",3);

    return 0;
}