!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.
-"'+//$/*
! Mécanismes de communication! !
! Les processus nʼont aucun espace mémoire en commun.#
1. Mémoire partagée!
! Certains processus peuvent coopérer pour réaliser une tâche#
2. Signaux!
" nécessitent le partage dʼinformations #
3. Tubes!
! Mécanismes de communication inter-processus permettent aux
4. Sockets#
processus de partager des informations #
5. Fichiers #
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
1. La mémoire partagée!
! #Attachement/détachement dʼun espace mémoire à lʼespace dʼadressage
partagé !
# Les processus peuvent accéder au même espace mémoire (segment) # ## # 0"&1*2/3#(,*!"&%,*#$%&'(""'"%/,*0"&1*2#$%)**+(""&%,*#$%,-"."/"
via lʼappel système shmget( )!
" "" " &%,*/3#1,*!"'"%/,*0"&1*2#$%)**+"."/#
# ## # int shmget ( key_t key, int size, int shmflg )#
! Si deux processus fournissent la même clé (key), ils accèdent au ! Désallocation de lʼespace mémoire partagé à lʼaide de la commande
même espace mémoire : espace de communication! cmd = IPC_RMID#
! Communication par lecture / écriture dans lʼespace partagé # **&%,*/3#',4*!"&%,*#$%0*(""&%,*'#1(""/,-$',*/3#&151/*212#$%0*"."/"
! Nécessite de faire attention à ne pas écraser les données de lʼautre#
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
2. Les signaux !
! Moyen de communication entre processus pour notifier
! Des signaux peuvent être envoyés à un processus par le système
ou par un autre processus !
dʼun événement#
# ## Exemple :! Ctrl+C # # Exemple #
# ## # # # " Le système envoie le signal SIGINT au processus en
# ## # # &%,*6&44"!".&15,"10*(""&%,*#0-34%"."/#
## # # # cours dʼexécution #
! Le système dispose dʼun ensemble de signaux #
! Plusieurs signaux possibles : SIGSTOP, SIGCONT, ,
o Certains ont une signification immuable comme le signal pour arrêter un
processus#
SIGSEGV, SIGINT, SIGTERM, SIGKILL, etc. #
o Certains peuvent être définis par lʼutilisateur #
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
! Signal handler : chaque processus a un code à exécuter par défaut 3. Les tubes!
pour chaque signal #
# ## # Exemple : ! exit() ! " Signal de fin de processus# ! Un tube est un fichier où un expéditeur/écrivain peut transmettre
des informations à un destinataire/lecteur.#
! Certains gestionnaires de signaux (signal handlers) peuvent être
! :;'(%&/#+*1+*'"##$%&'()"%*$%&1&-+')"%%+4*<**748"789+:%09:#"
réécrits pour faire tout autre chose#
;$);457")##<;0:7"="457"759+:7"*7"6)"9)>67"*7#"?;$07+#"<4@7+9#A#
o Définition dʼune fonction de traitement de signal!
! =%+*+%,-;+*+/,*(''+//&>4+*+%*4+',$-+*<*<1:+)B<5"*7#9+4;9+0;7"
! ! ! ,7.+1+8*0"&1*!"/&93(%14+-5,*2*."!"&%,*."/"
! =%+*+%,-;+*+/,*(''+//&>4+*+%*;'-&,$-+*<*-7#B<5"C&CD"*7#"*<55:7#":;+097#""""
* * * /&93(%14+-5,**/&9%(4*!"&%,**#0-34%(""/&93(%14+-5,""$)5*67+"."/ !
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
!"#$%&'E"I"G"" !"#$%&'E"F"G""
3.1. Les tubes anonymes ou ordinaires (pipes)!
@-&,+** -+(1**
# Lʼacquisition dʼun descripteur par un processus peut se faire par : # # #
! Un héritage des descripteurs du processus père après un fork( )! ! Ecriture dans un tube!
! Un appel de la primitive pipe( ) pour créer un nouveau tube anonyme#
# # # &%,**@-&,+!"&%,**94>'7#;EIGA*'3(-*2*19+>4KA**&%,**#0L7M4N7+"."/!
## # &%,**.&.+*!"&%,**2*94>'7#;"."/#
! Lecture dans un tube!
" " ?*94>'7#;"E"F"G"H"*7#;+01974+"1<4+"6)"67;94+7"#4+"67"94>7""" ## # # &%,**-+(1!"&%,**94>'7#;EFGA*'3(-*2*19+>4KA**&%,**#0L7M4N7+"."/#
" " ?"94>'7#;"E"I"G"H"*7#;+01974+"1<4+"6J:;+094+7"#4+"67"94>7""
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
3.2. Les tubes nommés ! ! Création dʼun tube nommé!
# ## # int mkfifo ( const char * pathname, mode_t mode )#
! Mécanisme introduit pour permettre à des processus sans lien de
parenté de communiquer.#
! Ouverture dʼun tube nommé !
! Etant nommé, il est référencé dans le système de gestion de fichiers#
# Ouverture bloquante (selon les systèmes) tant que les deux
! ! ! Tout processus connaissant la référence dʼun tube peut obtenir extrémités nʼont pas été ouvertes#
# via la primitive open( ) un descripteur en lecture et/ou écriture# # # " Notion de RDV entre deux processus en un point #
# particulier de leur exécution#
! Les descripteurs des deux extrémités du tube peuvent donc
être dans des processus différents# ! Suppression du tube avec la fonction unlink()!
!"##$%&'()"%*+%,-+*.-"'+//$/* !"##$%&'()"%*+%,-+*.-"'+//$/*
3.3. Opérations sur les tubes : Identiques aux opérations sur les fichiers !
@-&,+** -+(1** 0"&1*#(&%!."" " " " " " " " 0"&1*#(&%!."
# # E8"*C**
B-"'+//$/*C** B-"'+//$/*D** "O"""" " " " " " " " " "O"" "
-+(1** @-&,+** " '"%/,*'3(-*2#9+"P"QR766<"S<+6*TQ"/"" " " " '3(-*#9+"E"UV"G"/"""
E8"*D**
" &%,*K*"/" " " " " " " " " &%,*K*"/"
" #6E8""!"QW9%1W94>7X97#9Q(""FUUU"."/"" " " " K*"P"".+%*!"QW9%1W94>7X97#9Q("D2Y'D3Z["."/"
" K*"P"".+%*!"QW9%1W94>7X97#9Q(""D2\YD3Z["."/"" " -+(1*!"K*(""#9+(""UV"."/"
" @-&,+*!"K*(""#9+(""/,-4+%*!"#9+"."."/" " " " " '4"/+*!"K*"."/""
! Une communication dans les deux sens entre les processus
ne peut se faire quʼau moyen de deux tubes nommés# " '4"/+*!"K*"."/" " " " " " " " .-&%F*!"Q]4#9"+7;70@7*H"^_#^`5Q("#9+./"
}# !! ! ! ! ! ! ! ! ! ! $%4&%6*!"QW9%1W94>7X97#9Q"."/"
# # # !
! !! ! ! ! ! ! ! ! a!
H$,-+/*8"%')"%/I'"##(%1+/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! Endormissement dʼun processus! ! Créé par un processus, un thread peut être exécuté
indépendamment de son processus parent.#
# # # $%/&9%+1*&%,**/4++.*!"$%/&9%+1*&%,**#7;<5*#"."/#
! Il est caractérisé par un(e) : #
# # # - Identifiant du thread #
# # # - Etat courant du thread #
! Remplacement du programme courant par celui ciblé,
# # # - Contexte CPU #
dans le même processus#
# # # # - Registres CPU (sauvegardés à la suspension du thread )#
! ! ! &%,**+G+'4*!"'"%/,*'3(-*21)9$("";<5#9";$)+"b)+-(""AAA(""!'3(-*2."3cZZ"."/" M6<;"*7"e<59+f67""
- Compteur ordinal #
*J45"9$+7)*"!deM.""
- Priorité du thread #
* * ! - Pointeur vers le processus qui lʼa créé#
- Pointeurs vers ses threads fils #
J+/*K3-+(1/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! !! 1. Paradigmes de mémoire!
e+:)B<5" g+h9" i8:;4B<5" d7+%05:"
! Mémoire distribuée : chaque entité possède une mémoire
qui lui est propre#
jk7597" # ## # # " Cʼest le cas des processus#
! Mémoire partagée : chaque entité partage sa mémoire
Y79)+*:" avec les autres#
# ## # # " Cʼest le cas des threads#
M6<l4:"
# # Une allocation mémoire faite dans un thread est accessible
! par les autres threads !
Threads : transitions entre les états"
Z7#"d$+7)*#""
J+/*K3-+(1/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! !! 2. Création dʼun thread ! ! !! !
! !! ! int pthread_create( pthread_t *thread, const pthread_attr *attr,
## # # void *( * routine ) ( void * ), void *arg ) ;## #
! La création dʼun processus donne lieu à la création dʼun
thread natif exécutant la fonction main ().#
# ## " Cʼest le thread principal ou initial # ! Les attributs attr servent à paramétrer la création du thread,
NULL indique lʼutilisation des attributs par défaut#
! Les Pthreads créés ultérieurement par la primitive ! routine est un pointeur de fonction prenant un pointeur en
pthread_create( ) seront dits annexes ou auxiliaires# entrée, et retournant un pointeur#
! Lʼargument arg est le pointeur dʼentrée de routine()!
! !! pthread_create( ) : fonction équivalente à fork () #
! Le thread fils termine son exécution une fois la fonction pointée
par routine terminée#!
# #!
Z7#"d$+7)*#""
J+/*K3-+(1/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! !! 3. Terminaison dʼun thread! ! !! 4. Synchronisation de threads!
! Fonction à appeler par le thread, pour terminer son exécution ## ! Fonction à appeler par le thread père, pour attendre la fin de
lʼexécution du fils# # #
" " # int pthread_exit ( int *retVal ) ;# #
" " # int pthread_join( pthread_t thread_ID, void *retVal ) ;# #
Deux cas possibles : !
! Equivalente à wait( ) pour les processus#
! Toutes les ressources sont libérées : le thread est dit détaché#
! Lʼidentité et la valeur de retour (lʼadresse retVal) sont ! Attente ciblée, en utilisant lʼidentifiant thread_ID#
sauvegardées jusquʼà ce quʼun autre thread en prenne ! Valeur de retour du thread fils récupérée à lʼadresse retVal,
connaissance# cʼest-à-dire lʼadresse transmise par ce thread lors de lʼexécution
# " Equivalent à lʼétat de zombi dʼun processus # de pthread_exit( ).#
Z7#"d$+7)*#""
J+/*K3-+(1/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! !! Exemple! ! !! 5. Autre fonction!
void * print_string ( void *arg )#
{#
int pthread_yield ( ) ;# #
# char *str = ( char * ) arg ;#
# printf ( "Child says: '%s'\n", str ) ; #
# return NULL ;#
}#
! Abandon de la CPU par le thread, basculant alors dans la file
void main( ) ! dʼattente de lʼordonnanceur# #
{#
# pthread_t tid ;#
# pthread_create ( &tid, NULL, print_string, "Hello world!") ;#
# pthread_join ( tid, NULL ) ;#
}#
Z7#"d$+7)*#""
J+/*K3-+(1/* Z7#"d$+7)*#""
J+/*K3-+(1/*
! !! 6. Gestion de la concurrence!
! !! !
! !! ! ! Soit un programme parallèle calculant la somme des éléments ! Les threads accèdent au même tableau tab, sur des indices
## # # dʼun tableau# différents# #
# ## # # # int global_sum = 0 ;# ! Ils mettent à jour la même variable global_sum#
# ## # # # void *compute_array_sum ( void *arg ) #
# ## # # # {# ! Si deux threads mettent à jour la variable au même moment,#
# ## # # # int *tab = ( int * ) arg ; #
# # # # # # for ( i = start; i < end; ++ i ) # # # " comportement indéterminé#
# # # # # # {#
# # # # # # # global_sum += tab[ i ] ;#
# # # # # # }# Section critique : section du code où une variable est accédée
# # # # # # }# ## # en écriture par plusieurs threads. #