Contrôle Final 2 – Année 2019/2020
- Durée du contrôle : 2h
- Tous les documents sont autorisés
- Dans vos programmes, on ne vous demande pas de gérer les cas d'erreur
Le but de cet exercice est de créer un petit répartiteur de charge. Notre système est composé d'un processus maître et de processus esclaves. Le maître, lorsqu'il reçoit un travail à faire, choisit un esclave et délègue l'exécution de ce travail à l'esclave choisi.
En détail, lorsqu'un utilisateur soumet un travail, il indique le temps que va durer ce travail en secondes. Le maître choisit alors un esclave oisif, note l'instant où cet esclave aura terminé son travail (en additionnant la durée du travail à l'heure courante), puis lui délègue le travail.
Création des esclaves (7 points)
Le nombre d'esclaves (1,5 point)
État des esclaves (1 points)
Pour représenter l'état d'un esclave, on a besoin d'une structure de données contenant :
- le PID de l'esclave,
- une variable nommée end de type time_t et représentant l'heure à laquelle le dernier travail donné à l'esclave sera terminé (time_t est simplement un alias pour le type entier unsigned long long).
Après avoir donné la définition de cette structure que nous nommerons slave_state, donnez le code permettant de définir une variable globale nommée slaves stockant un pointeur vers un tableau de slave_state.
Allocation de l'état (1 point)
Donnez le code à ajouter au main pour stocker dans la variables slaves un pointeur vers un tableau de n structures slave_state alloué dynamiquement à l'aide de malloc.
Démarrage des esclaves (2 points)
Complétez votre fonction main de façon à créer n processus fils. Chaque processus fils doit être numéroté de 0 à n-1 et il doit appeler la fonction void wait_job(int i) où i est ce numéro. Le maître, de son côté, doit enregistrer le PID de l'esclave dans le tableau slaves à l'indice i. À cette question, on considère que la fonction wait_job vous est fournie. À terme, cette fonction contiendra contiendra le code exécuté par les fils.
Attente de la terminaison des esclaves (1,5 points)
Saisie des commandes (4,5 points)
Interaction avec l'utilisateur (2,5 points)
La fonction master doit exécuter une boucle infinie. À chaque itération de la boucle, la fonction master doit commencer par lire une ligne saisie par l'utilisateur que vous stockerez dans une variable locale cmd. Si cette ligne est exactement égale à exit, la fonction master doit appeler la fonction quit() avant de retourner dans le main. Si la ligne saisie n'est pas égale à exit, la fonction doit alors lire une seconde ligne, la convertir en entier et stocker ce nombre dans une variable locale nommée duration. Cette variable duration donne le temps, en secondes, que va mettre la commande cmd à s'exécuter. Enfin, la fonction master doit appeler la fonction void dispatch(char* cmd, int duration). On suppose aussi cette fonction est fournie. À terme, cette fonction va s'occuper de sélectionner un esclave et de transmettre la commande à exécuter à cet esclave.
- La fonction char* fgets(char* s, int size, FILE* stream); permet de lire une ligne à partir du flux stream (stdin dans notre cas). La fonction stocke le résultat dans le tableau de caractères s et s'assure que, au plus, seuls les size premiers caractères de la ligne seront stockés dans s.
- La fonction int strcmp(const char* s1, const char* s2) renvoie 0 si les chaînes pointées par s1 et s2 sont égales.
Terminaison des esclaves (2 points)
Délégation du travail à un esclave (5 points)
De façon à déléguer le travail à un esclave, nous procédons en trois étapes :
- la fonction int earliest() va trouver l'indice de l'esclave qui terminera son travail le plus tôt,
- la fonction int select(int duration) va sélectionner un esclave oisif pour exécuter une commande durant duration secondes et mettre à jour sa variable end de façon appropriée,
- la fonction void dispatch(const char* cmd, int duration) utilise select pour sélectionner un esclave puis s'occupe de déléguer le travail à l'esclave sélectionné.
Premier esclave prêt (1 points)
Sélection d'un esclave (2 point)
Délégation à l'esclave (2 points)
Traitement chez l'esclave (3,5 points)
Traitement chez l'esclave (2,5 points)
Problème de synchronisation (1 points)
- Maître ouvre, écrit cmd1, ferme
- Esclave ouvre, lit cmd1, ferme
- Maître ouvre, écrit cmd2, ferme
- Esclave supprime le fichier