Moniteur et section critique partagee |
Dans l'exemple precedent, les processus entraient en section critique
(appel a la methode qui_est_actif de
l'applet) en utilisant un mecanisme de semaphore. Si l'acces leur etait
refuse, ils pouvaient continuer a faire autre chose.
Dans d'autres situations, on peut imaginer que la section critique de code (plusieurs methodes) fasse partie du code d'un objet partage par plusieurs processus qui soient mis en sommeil en attendant d'entrer. |
![]() |
Java propose un mecanisme qui permet a un procesus d'un ensemble de processus de n'avoir acces a une methode dans la section critique d'un objet que si une condition liee a une variable est vraie d'une part et d'autre part d'exclure cet acces a d'autres processus. | ![]() |
(Mecanisme de moniteur propose par Hoare : "Communicating Sequential Processes". Communications of the ACM, Vol. 21, No. 8, August 1978, pp. 666-677). Un seul moniteur gere l'ensemble des methodes de la zone d'exclusion mutuelle. Une seule de ces methodes peut etre lancee a la fois. Un moniteur donne est attache a un objet donne (et vice versa).
Pour cela :
../..
public synchronized void ma_section_critique() { // a partir d'ici, le moniteur interdit l'acces aux autres processus while (condition) // la condition devra avoir change pendant le sommeil { try { wait(); } // le moniteur est relache et le processus endormi catch (InterruptedException e) { } } notifyAll(); // le moniteur est relache } |
Applet :
Programme (objet partage) :
class Section_critique
{ private int qui_entre ; private moniteur mon_pere ; Section_critique (moniteur papa) { qui_entre = 0 ; // par defaut mon_pere = papa ; } public synchronized void ma_section_critique(int numero, String nom) { while (qui_entre != numero) { try { wait() ; } catch (InterruptedException e) {} } qui_entre = (int) (Math.random()*mon_pere.NB_PROC) ; mon_pere.ecrit(nom+" est en SC. Le suivant est : " + qui_entre) ; notifyAll() ; } } |
Programme (corps des processus legers) :
class Hoare extends Thread
{ private StringBuffer mon_nom ; private moniteur mon_pere ; private int mon_numero ; private boolean ok ; Section_critique demande_acces ; Hoare(moniteur pere, String nom, int num, Section_critique sc) { super() ; ok = false ; mon_numero = num ; mon_nom = new StringBuffer(nom) ; mon_pere = pere ; demande_acces = sc ; } public void run() { while (! ok) { try { sleep(500) ; } catch (InterruptedException e) {} } while (true) { demande_acces.ma_section_critique(mon_numero, mon_nom.toString()) ; } } public void dit_ok() { ok = true ; } public void desactive() { ok = false ; } } |
Programme (de l'applet) :
import java.applet.* ; i
mport java.awt.*; public class moniteur extends Applet { final int NB_PROC=5 ; protected Hoare[] p ; protected int combien, ligne, total ; protected StringBuffer message ; protected Graphics gc ; protected boolean deja_lance ; private Section_critique demande_acces ; public void init() { int i ; // declare l'objet avec section critique demande_acces = new Section_critique(this) ; // declare le tableau de processus p = new Hoare[NB_PROC] ; for (i=0 ; i<NB_PROC ; i++) // alloue chaque processus { p[i] = new Hoare(this, "P"+i, i, demande_acces) ; } message = new StringBuffer() ; gc = getGraphics() ; } public void start() { ../.. } public void stop() { ../.. } public void destroy() { ../.. } public void paint(Graphics g) { g.setColor(Color.black) ; g.drawString(message.toString(), 5, 10*ligne) ; ligne ++ ; combien ++ ; if (combien == 10) { g.drawString("C'est fini.", 5, 10*(ligne+2)) ; stop() ; } } public boolean mouseDown(Event evt, int x, int y) { ../.. } public void ecrit(String msg) { message = new StringBuffer(msg) ; paint(gc) ; } } |
Ph. RIS 1997