• Aucun résultat trouvé

Systèmes d’exploitation CSI3531 Labo 2

N/A
N/A
Protected

Academic year: 2022

Partager "Systèmes d’exploitation CSI3531 Labo 2"

Copied!
5
0
0

Texte intégral

(1)

Systèmes d’exploitation

CSI3531 Labo 2

Communication entre processus avec des tuyaux Fils Java

Partie A – La communication entre processus avec tuyaux Objectif : Explorer le IPC avec les tuyaux UNIX/Linux Description

On réutilise les fichiers du laboratoire 1.

Étape 1 : Démarrez la machine virtuel Linux sitedev et faîtes un login au système.

Copiez le fichier « lab2afr.tar » fourni dans votre répertoire de travail (working

directory). Comme dans le labo 1, faites l’extraction des fichiers de cette archive avec tar –xvf lab2afr.tar. Vous retrouverez les mêmes fichiers que dans le labo 1 et un nouveau fichier filtre. Ceci est un fichier exécutable qui est exécuté sans paramètres, qui lit de son entrée standard, et qui est conçu pour lire la sortie de procmon du laboratoire 1 pour ensuite écrire seulement les lignes lorsque l’état du processus examiné change.

Étape 2 : Complétez le programme mon2.c (un gabarit vous êtes fourni) en suivant les lignes directrices suivantes :

1. Comme mon du labo 1, le programme mon2 reçoit un argument de la ligne de commande : le nom M du program qu’il doit exécuter.

2. Le programme mon 2 doit exécuter le programme M (le programme M ne prend aucun argument) et retenir dans PID l’identificateur du processus lancé.

3. Il doit ensuite exécuter procmon avec l’argument PID.

4. Il doit lancer un autre processus pour rouler le programme filtre sans arguments.

5. La sortie standard de procmon doit être envoyé à l’entré standard de filtre en utilisant un tuyau, i.e. filtre lira de son entré standard ce que procmon écrit à sa sortie standard.

6. Il attend 20 secondes, termine le programme M, attend encore un autre 2 secondes, et ensuite essaie de terminer procmon et filtre.

7. Un gabarit pour mon2.c vous êtes fourni pour vous aider à développer le programme.

Notez qu’une bonne partie du code de mon.c peut être copié à mon2.c.

Étape 3 : Compilez votre programme C avec la commande « cc mon2.c –o mon2 ».

Cette commande fait rouler le compilateur C (commande cc) pour compiler le code source mon2.c pour produire le fichier exécutable mon2. Si la compilation complète avec succès, le fichier exécutable mon2 se retrouvera dans le répertoire courant.

Étape 4 : Entrez la commande « mon2 calcloop » et observez. Cette commande lance le programme mon2 que vous avez créé, qui à son tour lance procmon pour

(2)

examiner l’exécution de calcloop et filtre pour imprimer seulement les lignes lorsque l’état de calcloop change.

Étape 5 : Vous pouvez expérimenter avec l’envoie de signaux au processus calcloop.

Après avoir exécuté mon2 calcloop & (& permet de pouvoir exécuter d’autres commandes) :

Déterminez le pid du calcloop (par exemple avec la commande ps).

Envoyez-y un signal d’arrêt avec la commande « kill –s SIGSTOP pid » où pid est le pid du calcloop déterminé au dernier point.

Envoyez-y un signal de départ avec la commande « kill –s SIGCONT pid ».

Notez que vous devez être rapide pour faire le tout à l’intérieur des 20 secondes que roule calcloop.

Information utile:

L’exécution d’un programme C commence par sa fonction main() qui comprends deux paramètres, l’entier argc qui donne le nombre d’arguments de la ligne de commande (qui a fait exécuter le programme) et un tableau de pointeurs à des chaînes de

caractères donnant accès aux arguments de la ligne de commande. Par convention, argv[0]¸donne le nom du programme et argv[1] donne le premier argument.

L’appel système fork() créée un nouveau processus. Le parent et l’enfant continue au même point, i.e., le retour de l’appel fork(). Mais chez le parent, fork() retourne le PID de l’enfant tandis que chez l’enfant, fork() retourne la valeur 0. Pour plus

d’information au sujet de fork(), utilisez man fork.

L’appel système execl(path, arg1, …) remplace l’image dans un processus par un programme avec des paramètres donnés. Tapez pour connaître la signification exacte de chacun des paramètres. L’appel execl(“calcloop”,”calcloop”,NULL) remplace le code dans le processus avec le programme calcloop. L’appel execl(“/bin/ls”, “ls”, “- l”, NULL) exécute le code du programme ls –l.

Vous devez convertir le nombre entier PID à une chaîne de caractère pour l’envoyer vers procmon. Ceci peut être fait en C avec une fonction de bibliothèque :

sprintf(pidchn,“%d”,pid), où pid est une variable int qui contient la valeur du pid, et pidchn est un tableau de caractères (char pidchn[20]) qui recevra la chaîne de caractères du PID à être envoyé vers procmon.

La fonction sleep() qui fera dormir le processus pour le nombre de secondes spécifié dans son paramètre.

L’appel système kill(pid,sig) qui envoie un signal sig au processus pid.

o Examinez signal.h pour connaître les différents signaux.

o Google est votre ami, le lien suivant suite à une recherche de « signal.h » peut être utile (il y en a beaucoup plus au sujet des appels et fonctions standards C) http://www.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html Un descripteur de fichier (file descriptor) est un nombre entier, qui sert de poignée (handle) pour identifier un fichier ouvert. Ce descripteur est utilisé avec d’autres fonctions ou systèmes d’appel tel que read() et write() pour faire des opérations E/S avec le fichier correspondant.

(3)

L’appel pipe(int *dfs) attend un argument qui est un pointeur à un tableau d’entier (i.e.

le nom d’un variable déclaré comme tableau d’int, i.e. int dfs[2], crée un tuyau, et retourne 2 descripteurs de fichiers dans le tableau reçu : dfs[0] contient la référence au bout de lecture du tuyau et dfs[1] contient la référence au bout d’écriture du tuyau.

dup2(int oldfd, int newfd) – clone (duplicate) le descripteur oldfd sur le descripteur de fichier newfd. Si newfd correspond à un fichier ouvert, ce fichier sera d’abords fermé.

Donc le même fichier peut être accéder soit par oldfd, soit par newfd (essentiellement deux connections au fichier). Voyez http://mkssoftware.com/docs/man3/dup2.3.asp ou

“man dup2” pour plus d’information. Par exemple, le programme suivant :

int main(int argc, char *argv[]) {

int df;

printf(“Bonjour le monde!”) df = open(“outFile.dat”, “w”);

if (df != -1) dup2(fd, 1);

printf(“Bonjour le monde!”);

close(df);

}

rédigera la sortie standard du programme au fichier “outFile.dat”. Le premier

« Bonjour le monde! » sera imprimer sur la console, tandis que le deuxième sera stocké dans le fichier « outFile.dat ».

read(int fd, char *buff, int bufSize) – lire du fichier (ou tuyau) identifier par le descripteur fd un nombre de caractères bufSize et copier les caractères lu dans le tampon buff. La fonction retourne le nombre de caractères lus (peut être moindre que bufSize), ou -1 lors d’une erreur, ou 0 lorsque la fin du fichier est atteint (dans le cas du tuyau, aucun processus est attaché au bout écrivant et aucune donnée existe dans le tuyau).

write(int fd, char *buff, int buffSize) – Écrit dans le fichier (ou tuyau) fd le nombre de caractères buffSize retrouver dans le tampon buff.

close(int fd) – ferme un fichier ouvert. Le descripteur fd pourra être réutilisé.

Cette liaison WEB pourrait vous aidez avec la programmation C : http://www.acm.uiuc.edu/webmonkeys/book/c_guide/

Linux/UNIX offre des pages de documentation (man pages). La commande man « nom de fonction » imprimera à l’écran de l’information détaillé au sujet de la fonction donnée.

(4)

Partie 2 – Les fils Java.

Objectifs :

1. Apprendre comment utiliser les fils – la classe Java Thread.

2. Apprendre comment utiliser les groupements de fils (thread pools) – la classe Java Executors.

Description

Dans cette partie du labo, vous travaillerez avec une application qui dessine une représentation de l’ensemble Mandelbrot. L’image sera générée en peinturant un

ensemble de rectangles dans une fenêtre Windows. En utilisant des fils (et groupement de fils) vous pouvez visuellement voir l’exécution des fils. Pour plus d’information sur cet ensemble MandelBrot et ses illustrations, consultez le site :

http://www.ddewey.net/mandelbrot/

Étape 1 – Votre première image de l’ensemble Mandelbrot : Faite l’extraction des fichiers java de l’archive MandelBrot.zip. Compilez le code java avec votre outil favori de développement java :

MBGlobals.java - Donne une classe contenant des données globales MBPaint.java - Donne une classe pour calculer la couleur des

pixels de l’illustration (elle colore aussi les pixels) dans un carré donnée de l’image.

MBCanvas.java - Donne la classe MBCanvas (extension de Canvas), une composante GUI qui permet de faire des dessins.

MBFrame.java - Donne la classe MBFrame (extension de JFrame), pour créer une fenêtre Windows. Un objet

MBCanvas est ajouté à cette fenêtre.

MandelBrot.java - On part d’ici. Mandlebrot traduira les arguments de la commande pour stocker ses valeurs dans MBGlobals. Ensuite, il créera un objet MBFrame pour faire apparaître une image de l’ensemble Mandelbrot selon les arguments de la commande.

Après avoir compilé l’application java, faite l’expérience de créer différentes vues de l’ensemble Mandelbrot avec la commande suivante:

java MandelBrot <Upper x Coord> <Upper y Coord> <Real Dim> <Pixel Dim> <Fill Dim>

<Upper x Coord> et <Upper y Coord>: sont les coordonnées du coin supérieur à gauche de l’illustration en termes de valeurs réelles. Pour avoir une vue général de l’ensemble, utilisez les coordonnées -2,2 avec une dimension de 4 (voir Real Dim).

(5)

<Real Dim> - L’application utilise un carré comme toile de fond. Sa valeur correspond à la dimension réelle du graphe de l’ensemble Mandelbrot. Donc la valeur 4 donnera une illustration avec les dimensions de 4X4 unités. Avec les coordonnées -2,2 pour le coin supérieur à gauche, le diagramme aura les coordonnées suivantes :

• -2, 2 (coin supérieur à gauche)

• 2, 2 (coin supérieur à droite)

• 2, -2 (coin inférieur à droite)

• -2, -2 (coin inférieur à gauche)

<Pixel Dim> - Cette dimension représente la dimension de la toile de fond en terme de pixels. Elle contrôle la grandeur de la fenêtre produite.

<Fill Dim> - Cette dimension contrôle la grandeur du carré pour remplir les pixels de l’illustration. Le code fourni, la récursivité est utilisé pour créer plusieurs objets MBPaint qui remplissent différentes sections de la toile de l’illustration (objet MBCanvas). L’objectif du lab est de changer le code afin d’utiliser des fils (threads) pour remplir ces différents carrés.

Essayez les arguments suivants :

java Lab3 -2 2 4 600 50 - Pour un vue générale. Modifiez 600 pour obtenir de différentes grandeurs de fenêtres.

D’autres vues intéressantes sont possibles avec le suivant:

java Lab3 -2 1 1 600 50 java Lab3 -1 1 1 600 50 java Lab3 -2 0.5 1 600 50

Étape 2 - L’Utilisation des fils: Avec la classe Thread de Java, modifies le code fourni afin d’utiliser des fils (threads) différents pour remplir chaque carré de remplissage.

Modifier le paramètre <Fill dim> pour voir l’effet du remplissage de l’illustration. Notez que lorsque vous réduisez la valeur de ce paramètre, le nombre de fils utilisés augmente.

Étape 3 - L’utilisation du groupement de fils (thread pool) : Java offre la classe

« Executors » pour la création de groupements de fils. La méthode statique

« newFixedThreadPool(int nFils) » créer un objet de la classe ExecutorService qui gère un groupement de nFils fils. Pour créer un tel objet gérant 20 fils, utilisez :

ExecutorService thpool = Executors.newFixedThreadPool(20);

Des tâches peuvent être exécutées avec:

thpool.execute(Runnable task)

Notez que la tâche « task » est un objet qui implémente l’interface Runnable. Consultez la documentation Java pour les détails de l’utilisation de la classe Executors et l’interface ExecutorService.

Modifiez le code Java pour utiliser un groupement de fil qui exécutera les tâches définies par les objets MBCompute. Vous devez voir l’effet de limiter le nombre de fils qui peuvent exécuter à la fois, surtout en comparant le comportement avec la version l’étape 2). Essayez de varier la grandeur du groupement (nombre de fils) pour voir l’effet de l’exécution.

Références

Documents relatifs

Copiez le fichier « lab1.tar » dans votre répertoire courant sur le système Linux et faite l’extraction des fichiers (untar) avec la commande tar -xvf lab1.tar.. Vous trouverez les

Cette valeur correspond au nombre maximum d’élément pouvant être placé Cette valeur correspond au nombre maximum d’élément pouvant être placé dans le tableau, il est

Le code source Java est compilé non pas pour un processeur donné, mais pour une machine virtuelle (c'est-à-dire qui n'a pas d'existence physique), la JVM (Java Virtual Machine)..

Vous devez classer les tâches ci-dessous pour mener ce projet à bien, pour cela vous devez créer un planning d'activités sur le logiciel Gantt Projet :.. Distributon des rôles

La ceinture moyenne peut supporter une étagère pour objets plus légers, cette étagère s'appuie sur la table par un de ses côtés et forme équerre avec

2 Malgré le premier alinéa, il peut les conserver sous réfrigération pour au plus 14 jours suivant la mort de l’animal ou sous congélation pour au plus 240 jours suivant cette

• Chaque classe enveloppe poss`ede des m´ethodes pour extraire la valeur d’un objet : primitifValue() appliqu´ee sur l’objet enveloppe renvoie une valeur de type primitif.. •

• Chaque classe enveloppe poss`ede des m´ethodes pour extraire la valeur d’un objet : primitifValue() appliqu´ee sur l’objet enveloppe renvoie une valeur de type primitif.. •