12
EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

Embed Size (px)

Citation preview

Page 1: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 1

Cours de CPI

Philippe Bancquart

CPI 2005

Page 2: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 2

Communication entre les processus Possible par fichiers

Sous Unix, pipes signe |

Le premier fournissant des données que le second exploite au fur et à mesure de leur production.

Les messages forment un mode de communication privilégié entre les processus

Sous Unix ou DOS

dir | moreUn fil écrit dans

PipedOutputStreamUn autre fil lit dans

PipedInputStreamLe tube

Page 3: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 3

Messages

Les communications de messages se font à travers deux opérations fondamentales :Envoie(message) et reçois(message). (send et receive). Les messages sont de tailles variables ou fixes. Les opérations d’envoi et de réception peuvent être soit directes entre les processus, soit indirectes par l’intermédiaire d’une boîte aux lettres.

P : envoie(Q,message)

Q:reçois(P,message)

Q:envoie(P,acquittement)

P:reçois(Q,message)

On peut concevoir des applications qui communiquent à travers un segment de mémoire partagée.

Page 4: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 4

Producteur envoie messageconsommateur reçoit Entre les 2 zone stockage : BUFFER

Producteur P(vide)Produire(message)Déposer(case,message)V(plein) 

Le consommateur est en sommeil, un producteur met un message et prévient le consommateur par Wakeup. Le consommateur lit le message et décrémente le nombre de message.

Consommateur P(plein) Retirer(case,message)Consommer(message)V(vide)

Le problème vient quand le producteur veut mettre des informations alors que la file est pleine. Le producteur devra dormir jusqu’à ce que le consommateur ait vidé au moins une place. De même le consommateur dort jusqu’à ce que une information soit mise.

Page 5: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 5

Exemple codeVar Tampon: tableau[1…N] de messages

Mutex: Sémaphore initialisé à 1

PlaceDispo: Sémaphore initialisé à N

ElémtDispo: Sémaphore initialisé à 0

Producteur

Var in = 1

Boucle

Produire (mess)

P (PlaceDispo) /* placeDispo arret si 0 */

P (Mutex) /*zone critique*/

Tampon[in] <- message

V (Mutex) /*fin zone critique*/

V (ElémtDispo) /* +1 donc element dispo */

Fin boucle

Consommateur

Var out = 1

Boucle

P (ElémtDispo) /* si >=1

P(Mutex) /*critique*/

Message<- Tampon[out]

V(Mutex)

V(PlaceDispo) /+1 place*/ Conso(mess)

Fin boucle

Page 6: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 6

remarque en java nous n'avons pas de sémaphores, alors on écrit des moniteurs.

On peut réaliser ceci par une classe Tampon qui dispose de fonctions put() et get() synchronisées qui respectivement écrivent et lisent les messages:

put() écrit dans le tampon. S’il y a quelque chose, il attend qu’il se vide.

get() lit la valeur du tampon et le met à zéro. S’il n’y a rien, il attend qu’il se remplisse

Page 7: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 7

Producteur Consommateur#

void producteur (void) {

{

int objet ;

while (TRUE) {

produire_objet (&objet) ;

if (compteur ==N) sleep() ;

mettre_objet(objet) ;

compteur++ ;

if (compteur >=1) wakeup(consommateur) ;

}

void consommateur (void) {

{

int objet ;

while (TRUE) {

if (compteur ==0) sleep() ;

retirer_objet (&objet) ;

compteur-- ;

if (compteur <=N-1) wakeup(producteur) ;

consommer_objet(objet)

}

Page 8: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 8

Monitor ProducteurConsommateur

Monitor Condition plein, vide ;Int compteur ;Procedure mettre(){If compteur == N then wait(plein) ;

Mettre_objet ;compteur = compteur +1 ;If compteur =1 then signal (vide)

}

Procedure retirer(){

If compteur == 0 then wait(vide) ;

retirer_objet ;

compteur = compteur -1 ;

If compteur =1 then signal (plein)

}

compteur=0 ;

Procedure producteur

While (TRUE){

Produire_objet ;

ProducteurConsommateur.mettre ;

}

Procedure consommateur

While (TRUE){ProducteurConsommateur.retirer;

utiliser_objet ;

}

Page 9: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 9

Production de messages#include " prototype "#define N 100#define Taille 4 typdef int message[taille];

void producteur(void){

int objet;

message m;

while (TRUE) {

produire-objet(&objet);

receive(consommateur, &m);

faire-message(&m,objet);

send(consommateur, &m);

}

}

void consommateur(void){

int objet, i ;

message m;

for (i=0;i<N;i++)

send(producteur , &m);

while (TRUE) {

receive(producteur, &m);

retirer-objet(&objet);

send(producteur, &m);

utiliser_objet(objet);

}

}

Page 10: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 10

Exemple de code

class Tampon {

private String data = null;

public synchronized boolean put(String put_data) {

// Si quelque chose écrit on attend

while (data != null) {

try {

wait();

} catch (InterruptedException e) {}

} data = put_data;

// Les autres peuvent se réveiller

notifyAll();

return true;

}

public synchronized String get() {

while (data == null) {

try {

wait();

} catch (InterruptedException e) { }

}

String get_data = data;

data = null;

notifyAll();

return get_data;

}

}

Page 11: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 11

Echange de messages Si l’on communique sur des machines différentes, il

ne faut pas perdre de messages. Par convention on peut convenir que le récepteur à la réception du message retourne un acquittement. L’émetteur envoie de nouveau le message si au bout d’un délai, il n’a pas reçu d’acquittement.

Si c’est l’acquît qui est perdu, alors le producteur retransmet le message, dans ce cas c’est le récepteur qui doit faire la différence qu’il s’agit du même message.

Pour cela généralement on numérote les messages.

Page 12: EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/2005 - page 1 Cours de CPI Philippe Bancquart CPI 2005

EPID-CPI-ISAIPPhilippe Bancquart - mise à jour 24/02/2005 - page 12

Fonction SEND et RECEIVE.

On utilise une boîte aux lettres (mailbox), c’est un espace de mémoire qui contient des messages. Si un producteur envoie et que la boîte est pleine il sera suspendu.

Sous Unix IPCS, la taille de la BAL est déterminée dans le système, limite en nombre de messages et la taille totale.

Pour se retrouver, les processus possède une clé, pour accéder à leurs BAL.