Telechargé par hafsa elalami

tp2-correction

publicité
Licence Informatique
Système d’exploitation
Multi-Processing - premiers pas
Exercice 1 : Exécution concurrente des processus père et fils
Ecrire un programme qui crée un fils.
3 Le père affiche : « Je suis le père mon PID est ... et mon PPID est ... ».
3 Le fils affiche : « Je suis le fils mon PID est ... et mon PPID est ... ».
Rajouter l’appel à la primitive sleep pour voir les exécutions possibles :
1. Le fils se termine avant le père,
2. Le père se termine avant le fils.
#include < s t d i o . h>
#include <u n i s t d . h>
void main ( )
{
pid_t p ;
p=f o r k ( ) ;
switch ( p )
{
case ( 0 ) :
// s l e e p ( 1 5 ) ;
p r i n t f ( " Le f i l s
p i d e s t =%d e t mon p p i d e s t=%d\n" ,
getpid () ,
getppid ( ) ) ;
break ;
case ( − 1 ) :
// s l e e p ( 1 5 ) ;
p r i n t f ( " E r r e u r f o r k \n" ) ;
break ;
default :
p r i n t f ( " Le p e r e p i d e s t =%d e t mon p p i d e s t=%d\n" ,
getpid () ,
getppid ( ) ) ;
}
p r i n t f ( " Fin du p r o c e s s u s %d\n" , g e t p i d ( ) ) ;
}
Exercice 2 : Héritage des attributs et copies des variables
Reprendre le programme ci-dessus et compléter en affichant l’uid, le gid, et le contenu d’une variable x
initialisée à 2 (avant le fork) et modifié selon x+3 par le fils et selon x*5 par le père.
#include<u n i s t d . h>
#include<s t d i o . h>
void main ( )
{
pid_t p ;
int x = 2 ;
p=f o r k ( ) ;
switch ( p )
{
case ( 0 ) :
x = x + 3;
p r i n t f ( " Le f i l s p i d=%d p p i d=%d u i d=%d g i d=%d x=%d\n" ,
getpid () ,
getppid () ,
getuid () ,
getgid () ,
Université de Pau et des Pays de l’Adour
Licence Informatique
Système d’exploitation
x);
break ;
case ( − 1 ) :
p r i n t f ( " E r r e u r f o r k \n" ) ;
break ;
default :
x = x ∗ 5;
p r i n t f ( " Le f i l s p i d=%d p p i d=%d u i d=%d g i d=%d x=%d\n" , g e t p i d ( ) ,
getppid () ,
getuid () ,
getgid () ,
x);
}
p r i n t f ( " Fin programme \n" ) ;
}
Exercice 3 : Cas particulier des descripteurs de fichiers
Ecrire un programme qui ouvre un fichier nommé « toto », en lecture et écriture, dont le contenu est la suite
123456789. Le programme fork ensuite ; le fils écrit ab dans le fichier ensuite il s’endort et il lit 2 caractères ; le
père s’endort, lit 2 caractères et écrit AB.
/∗ Le d e s c r i p t e u r n e s t pas d u p l i q u é c a r i l e s t s t o c k é dans l a t b l d e s f i c h i e r s ∗/
/∗ e t non dans l a t b l d e s d e s c r i p t e u r ( p r o p r e à chaque p c s ) ∗/
#include<s t d i o . h>
#include<f c n t l . h>
#include<u n i s t d . h>
#include<s y s / s t a t . h>
#include<s y s / t y p e s . h>
void main ( )
{
pid_t p ;
char c h a i n e [ 3 ] ;
int desc ;
d e s c=open ( " t o t o " ,O_RDWR, 0 ) ;
p=f o r k ( ) ;
switch ( p )
{
case ( 0 ) :
p r i n t f ( " Le f i l s PID=%d PPID=%d\n" ,
getpid () ,
getppid ( ) ) ;
read ( desc , chaine , 2 ) ;
c h a i n e [ 2 ] = ’ \0 ’ ;
p r i n t f ( " c h a i n e l u e pa r l e f i l s %s \n" , c h a i n e ) ;
sleep (10);
c l o s e ( desc ) ;
break ;
case ( − 1 ) :
p r i n t f ( " E r r e u r f o r k \n" ) ;
break ;
default :
p r i n t f ( " Le p è r e V a l e u r de r e t o u r du f o r k=%d\n" , p ) ;
p r i n t f ( " Le p è r e PID=%d PPID=%d\n" ,
getpid () ,
getppid ( ) ) ;
sleep (3);
read ( desc , chaine , 2 ) ;
c h a i n e [ 2 ] = ’ \0 ’ ;
p r i n t f ( " c h a i n e l u e pa r l e p è r e %s \n" , c h a i n e ) ;
sleep (20);
w r i t e ( d e s c , "AB" , 2 ) ;
c l o s e ( desc ) ;
}
p r i n t f ( " Fin du Programme\n" ) ;
}
Exercice 4 : Synchronisation des processus père et fils par le wait
Ecrire un programme qui crée un fils et affiche, pour chacun des processus le PID et PPID dans l’ordre :
Fils puis père si l’on passe « synchro » comme paramètre, exécution des processus dans l’ordre décidé par
l’ordonnanceur sinon.
Université de Pau et des Pays de l’Adour
Licence Informatique
Système d’exploitation
#include<u n i s t d . h>
#include<s t d i o . h>
#include<e r r n o . h>
#include<s t r i n g . h>
void main ( i n t a r g c , char ∗ a r g v [ ] )
{
pid_t p i d ;
int s t a t u t ;
i f ( ( a r g c ==2) && ( strcmp ( a r g v [ 1 ] , " s y n c h r o " ) ! = 0 ) )
{
p r i n t f ( " L a n c e r l e programme a v e c un argument : \ n" ) ;
p r i n t f ( " \ t Synchro pour a f f i c h e r l e f i l s p u i s l e p e r e \n" ) ;
p r i n t f ( "Aucun argument s i n o n . \n" ) ;
}
else
{
s ys tem ( " c l e a r " ) ;
p r i n t f ( " \n\ t \ t \tGENERATION AUTOMATIQUE DE PROCESSUS\n\n" ) ;
pid = f o r k ( ) ;
switch ( p i d )
{
case −1:
perror (" erreur fork :\ t" ) ;
break ;
case 0 :
sleep (1);
p r i n t f ( " f i l s PID : %d \ t PPID : %d\n" ,
getpid () ,
getppid ( ) ) ;
break ;
default :
i f ( ( a r g c ==2) && ( strcmp ( a r g v [ 1 ] , " s y n c h r o " )==0))
{
w a i t (& s t a t u t ) ;
p r i n t f ( " p e r e PID : %d \ t PPID : %d\n" ,
getpid () ,
getppid ( ) ) ;
}
else
{
p r i n t f ( " p e r e PID : %d \ t PPID : %d\n" ,
getpid () ,
getppid ( ) ) ;
w a i t (& s t a t u t ) ; } /∗ E v i t e r un p r o c e s s u s zombie ∗/
}
p r i n t f ( " \n\ t F i n du programme . PID : %d\n" , g e t p i d ( ) ) ;
}
}
Exercice 5 : Attente et passage de paramètres
Ecrire un programme dont le fonctionnement est le suivant :Il lit sur la ligne de commande (utiliser argc
et argv) le nombre N de processus à créer. Il crée ces N processus en faisant N appels à fork (cf. plus loin la
tâche assignée à ces processus).Il se met en attente (appel à Pid_Fils = wait(&Etat)) de ces N processus fils et
visualise leur identité (Pid_Fils et valeur de Etat) au fur et à mesure de leurs terminaisons (Pour attendre la
fin de tous les fils, utiliser le fait que wait renvoie la valeur -1 quand il n’y a plus de processus fils à attendre).
Chacun des processus fils Pi exécute les instructions suivantes : il visualise son pid (getpid) et celui de son
père (getppid), puis il se met en attente pendant 2*i secondes (sleep (2*i)), et visualise la fin de l’attente, puis
se termine par exit (i).
#include<u n i s t d . h>
#include<s y s / w a i t . h>
#include<s t d i o . h>
#include<s t d l i b . h>
#include<e r r n o . h>
#include<s t r i n g . h>
i n t main ( i n t a r g c , char ∗ a r g v [ ] ) {
pid_t pid , p i d F i l s ;
int statut , i , iReturn ;
Université de Pau et des Pays de l’Adour
Licence Informatique
Système d’exploitation
i n t iNbProc ;
i f ( argc !=2)
{
p r i n t f ( " L a n c e r l e programme a v e c un argument : \ n" ) ;
p r i n t f ( " \ t l e nombre de p r o c e s s u s f i l s a c r e e r \n" ) ;
}
else
{
s ys tem ( " c l e a r " ) ;
p r i n t f ( " \n\ t \ t \tATTENTE AUTOMATIQUE DE LA TERMINAISON DES FILS \n\n" ) ;
iNbProc = a t o i ( a r g v [ 1 ] ) ;
f o r ( i =0; i <iNbProc ; i ++)
{
pid = f o r k ( ) ;
i f ( p i d==−1){
perror ( " Creation f i l s " ) ;
e x i t ( −1);
}
else i f ( pid !=0){
/∗ code p e r e ∗/
continue ;
}
else {
/∗ code f i l s ∗/
p i d F i l s=g e t p i d ( ) ;
f p r i n t f ( stdout ,
" F i l s num:%d de p i d %d e t de %d\n" , i ,
pidFils ,
getppid ( ) ) ;
s l e e p (2∗ i ) ;
f p r i n t f ( stdout ,
" F i l s num:%d de p i d %d e t j e me t e r m i n e \n" , i ,
pidFils );
exit ( i );
}
}
/∗ Les f i l s s o n t c r e e s . Le p e r e s e met en a t t e n t e ∗/
while ( 1 )
{
i R e t u r n=w a i t (& s t a t u t ) ;
i f ( i R e t u r n==−1)
break ; /∗ r e t u r n −1 quand i l ne r e s t e p l u s de f i l s a a t t e n d r e ∗/
else
{
/∗ l a f o n c t i o n WEXITSTATUS r e t o u r n e l a v a l e u r t r a n s m i s e par l e e x i t ∗/
f p r i n t f ( stdout ,
" Je s u i s l e p e r e de p i d %d e t mon f i l s de p i d %d s e t e r m i n e a v e c l e
getpid () ,
iReturn ,
WEXITSTATUS( s t a t u t ) ) ;
}
}
f p r i n t f ( stdout ,
" Je s u i s l e p e r e de p i d %d e t j e me t e r m i n e \n" ,
getpid ( ) ) ;
}
return ( 0 ) ;
}
Exercice 6 : Recouvrement d’un processus,interpréteur
Ecrire un interpréteur simple de commandes externes (exemples ps, ls, gcc, ...).
#include
#include
#include
#include
< s t d i o . h>
<e r r n o . h>
<u n i s t d . h>
< s t r i n g . h>
void main ( i n t a r g c , char ∗ a r g v [ ] )
{
pid_t p i d ;
int i , statut , a ;
char commande [ 1 0 ] ;
s t r c p y ( commande , " " ) ;
while ( strcmp ( commande , " e x i t " ) ! = 0 )
Université de Pau et des Pays de l’Adour
st
Licence Informatique
Système d’exploitation
{
p r i n t f ( "$" ) ;
fflush ( stdin );
s c a n f ( "%s " , commande ) ;
pid = f o r k ( ) ;
switch ( p i d )
{
case −1:
p e r r o r ( " e r r e u r de f o r k \n" ) ;
e x i t ( −1);
case 0 :
p r i n t f ( "%s PPID = %d , PID = %d \n" ,
commande ,
getppid () ,
getpid ( ) ) ;
i f ( strcmp ( commande , " e x i t " ) ! = 0 )
e x e c l p ( commande , commande , NULL ) ;
perror (" execlp " ) ;
// i l ne f a u t pas que l e f i l s c o n t i n u e
e x i t ( −1);
default :
p i d = w a i t (& s t a t u t ) ;
i f ( p i d==−1)
per ro r ( " l e wait " ) ;
else
p r i n t f ( " p r o c e s s u s zombi %d\n" , p i d ) ;
}
}
p r i n t f ( " \n \ t t o u t e s t t e r m i n e \n" ) ;
}
Université de Pau et des Pays de l’Adour
Téléchargement