TP ‐ Processus - vbridonneau/CoursSysteme GitHub Wiki

TP Processus

Un peu de topologie

Création d'une chaîne de processus

Dans cet exercice, l'objectif est de créer une ligne de processus d'une certaine hauteur H. Pour ce faire, nous allons réutiliser les fonctions fork et wait afin de pouvoir créer et attendre des processus. L'objectif est de créer H processus de la façon suivante : un processus crée un processus fils, attend que son fils termine puis fais un calcul (on pourra simuler le temps de calcul par une pause) et enfin affiche son identifiant de processus ainsi que celui de son père termine son exécution.

  1. Écrire une version itérative permettant de créer une chaine de H processus en utilisant une boucle for. On pourra définir H comme une constante.

  2. Écrire une version récursive de la ligne.

On peut s'assurer que l'on a bien créé une chaine de processus à partir de l'affichage en sortie.

  1. Comment s'assurer que l'on a bien créé une ligne de processus ?

Création d'une étoile de processus

Mainteneant que l'on sait créer une chaîne de processus, on peut essayer d'aller plus loin et de créer une étoile de processus. Une étoile de processus consiste en un processus central et un certain nombre de processus fils.

  1. Créer une étoile de processus. Le nombre de processus fils créé pourra être stocké dans une constant H comme dans le précédent exercice. (Vous pouvez réfléchir à un moyen d'adapter le code utiliser pour produire une chaîne de processus et l'adapter à l'étoilé).

Pour ajouter un peu d'interêt à notre programme, on peut essayer de communiquer des informations entre les processus. Dans un premier temps, on pourra essayer de communiquer au processus principal une valeur aléatoire comprise entre 1 et 10 (inclus) et d'afficher la somme dans le père.

  1. En utilisant la fonction wait et le status que l'on peut passer en argument, faîtes en sorte que les processus fils renvoit un nombre aléatoire compris entre 1 et 10 inclus.

Une autre façon de communiquer entre les processus est d'utiliser la fonction pipe pour communiquer entre les processus. En utilisant une telle fonction, il est possible, via les entrées et sorties standards redirigés, ainsi qu'en utilisant les fonctions write et read d'envoyer/recevoir des chaînes de caractères entre les processus.

  1. Ajouter la création d'un processus dans le processus principal pour que ce soit un fils de ce dernier qui fasse l'affichage de la somme dans la console.

Plus grande voyelle dans un fichier

Dans l'exercice qui suit, notre but est de compter, pour un fichier donné, le nombre de voyelles qu'il contient. Pour ce faire, nous allons créer un programme qui prend en argument les fichiers à traiter et qui, pour chacun, crée un nouveau processus (via fork), appelle un fonction pour compter le nombre de voyelle dans le fichier et renvoie, par le status (argument de exit) le nombre de voyelles présent dans le fichier. Commençons par la fonction qui compte les voyelles.

  1. Créez une fonction compterVoyelle permettant, pour un fichier donné, de retourner la voyelle de plus grande occurence qu'il contient. Voici son prototype :
unsigned char compterVoyelle(const char *nomFichier);

Note: On pourra utiliser le code suivant pour savoir si un caractère c est une voyelle ou non :

if(strchr("aeiouyAEIOUY", c) != NULL) {
    /* Faire quelque chose. */
}

Il ne nous reste plus qu'à utiliser cette fonction et fork pour compter les voyelles par fichier. Pour ce faire, notre programme comportera deux boucles : une pour créer les processus et une pour les attendres afin de d'afficher le résultat.

  1. Codez la boucle for permettant la création des processus. Pour chaque processus créé, le père mémorise le pid de son fils dans un tableau et le fils lui, exécute la fonction puis sort du programme en passant en status le nombre de voyelle du fichier traité.

  2. Codez la boucle for permettant d'attendre les processus et afficher ensuite le fichier contenant le plus de voyelle.

Communication entre processus

Dans cet exercice, l'objectif est de pouvoir communiquer entre plusieurs processus en utilisant des canneaux de communications. Ces cannaux peuvent être créés en utilsant l'appel système pipe permettant une communication unidirectionnelle entre deux processus, souvent un père et son fils. Dans cette exercice, nous allons utiliser ces processus pour créer une étoile de processus faire en sorte que chaque fils envoie un nombre aléatoire entre 1000 et 1999 inclus. Le père se chargera alors de sommer ces nombres et de d'afficher le résultat dans le terminal. Le nombre de fils à créer sera passé en argument à la fonction main.

Nombre de noeud d'un arbre

Pour cet exercice, notre but est de compter le nombre de noeud que possède un arbre binaire d'une certaine hauteur h. Pour ce faire, nous allons implémenter une fonction récursive arbre dont le but est de créer les processus via des appels à fork, puis de récupérer via le status et la fonction wait le nombre de noeud créé par les processus fils. La fonction que l'on va créer aura le prototype suivant :

void arbre(int hauteur);

Note : Comme cette fonction se contente de sortir du programme sans retourner de valeur, son type de retour est void. Dans un premier temps, nous allons commencer par écrire le code de la fonction main qui va appeler arbre en lui passant en paramètre une valeur entière lu depuis depuis les arguments du programme. Même si on ne connaît pas encore le contenu de la fonction arbre, on connaît néanmoins son comportement. On va donc pouvoir l'utiliser pour récupérer le nombre de noeud d'un arbre binaire de taille h.

  1. Ecrivez le code de la fonction main de telle manière à pouvoir récuperer la nombre de noeud d'un abre de hauteur h.

Avant de coder notre fonction arbre, on peut se demander quel résultat est censé donner une telle fonction :

  • Combien de noeud possède un arbre de hauteur h ?

On va à présent pouvoir écrire le code de la fonction arbre. Etant donné que notre fonction est récursive il va falloir gérer le cas général et le cas terminal.

  1. Commencez par gérer le cas ou la hauteur de l'abre vaut 1.
  2. Écrivez ensuite le cas général. On oubliera pas que notre fonction ne renvoit rien; elle se contente de créer des processus qui vont eux appeler la fonction arbre.

Test

Testez votre programme avec les hauteurs suivantes :

  1. 1, 5, 7, 9. Est-ce que ces valeurs correspondent à la valeur théorique calculée précédement ?
⚠️ **GitHub.com Fallback** ⚠️