Pages professionnelle – Thomas Robert

Maître de Conférence

Diviser pour régner

Ce Tp a pour but de vous faire réaliser le motif de conception diviser pour régner.

Nous vous demandons d’écrire un programme qui acceptera pour paramètres une chaine de caractère string suivie d’une liste non vide de chemins vers des fichiers, list (tout ceci passé via la ligne de commande). L’exécution de ce programme consiste à exécuter le binaire de grep dans un processus différent sur chaque fichier dont le nom est passé en paramètre pour y chercher la chaîne de caractère string.

Ceci correspond à paralléliser l’exécution du programme grep quand ce dernier est appelé sur N, N>1, fichiers. Les étapes de ce travail sont
1) de comprendre comment grep est appelée, et ce que grep « retourne en tant que processus » (ie. ce qui est passé en paramètre à exit ou return dans main. (voir l’annexe).
2) coordonner la création d’autant de processus que nécessaire et le chargement de grep dans chacun d’eux avec le bon ensemble de paramètres
3) Synchroniser la fin d’exécution du processus parent avec le/les processus enfant(s). Attention, la démarche n’a d’intérêt que si les processus enfants peuvent effectivement s’exécuter en parallèle.

Ainsi, si votre programme est compilé pour produire l’exécutable parallel_grep, alors l’exécution de la commande :

./parallel_grep "Lac" f1 f2 f3

Ceci doit correspondre à l’exécution en parallèle de chacune des commandes suivantes :

  • grep "Lac" f1
  • grep "Lac" f2
  • grep "Lac" f3

Puis si « Lac » est trouvé dans au moins un des fichiers, vous devez afficher « Lac trouvé » et sinon « Lac absent »

Ecrivez le code de parallel_grep

Nous testerons tout ceci sur des fichiers contenant des nombres et des motifs correspondant eux mêmes à des nombres. Vous pouvez utiliser les fichiers placés dans le répertoire suivant /cal/homes/trobert/dataTP1 pour vos tests. Vous pouvez générer de nouveaux fichiers de donnée en utilisant l’exécutable sd (searchdata) présent dans /cal/homes/trobert/dataTP1. Recopiez le et pour le lancer utiliser 3 paramètre le nombre de lignes dans le fichier, le nom du fichier de sortie et un entier choisi au hazard pour initialiser le générateur aléatoire. Utilisez des petits fichiers pour tester les deux comportements attendus au départ.

Vous pouvez utiliser time <cmd> pour mesurer la consommation de ressource CPU mais aussi le temps de réponse de votre commande. Comparez parallel_grep à grep dans différents cas

Observez les différences de temps CPU consommé / temps de réponse pour grep et parallel grep sur un ensemble de petits fichiers et un ensemble de gros fichier. Qu’en concluez vous ?

Annexe sur le fonctionnement de grep

Pour rappel grep permet de rechercher les concordances entre une expression régulière et le contenu d’un fichier ou de l’entrée standard. Par défaut grep affiche la ligne où la concordance de l’expression régulière est trouvée. 

Prenons un exemple simple :  

Dans le répertoire /cal/homes/trobert/dataTP1 se trouvent 4 fichiers contenant au format texte une liste de nombres (un par ligne). 
Si vous recherchez dans ces fichier à savoir combien l’on trouve l’expression régulière « 12345 » il faut saisir 

grep -c "12345" /cal/homes/trobert/dataTP1/data1

Lors de l’exécution de cette commande le shell va
1- créer un nouveau processus appelé « descendant »
2- exécuter la fonction execve pour charger le binaire de grep dans le processus descendant
3- le code de grep démarre son exécution depuis le main du binaire de grep et se termine lors de l’appel à return dans le main ou exit depuis n’importe quelle fonction appelée par main

La valeur passée à return dans le main ou à exit est consultable en ligne de commande pour la dernière commande exécutée via : echo $?