Gestion de la priorite des processus |
Schema du programme :
Applet (secouer legerement et regulierement la souris pour que cela marche !):
L'affichage par paint semble faire appel a un processus leger dont on ne controle pas vraiment le declenchement : un update par exemple ne garantit absolument pas une mise a jour immediate, ce qui peut se traduire ici par un changement de l'etat de ce qu'il y a a afficher avant que cela soit effectivement affiche.
Important sur notre exemple : pour empecher une mise a jour intempestive de ce genre, nous utilisons un booleen en guise de semaphore et ce semaphore est libere par le paint. Il faut donc effectivement garantir que l'on va rentrer dans ce paint pour que tout le monde ne se retrouve pas definitivement bloque (l'applet ne semble pas etre en mesure de recuperer autoritairement la main). Un yield repond a cette exigence.
Helas, ce n'est pas encore suffisant car l'affichage est tres saccade et non regulier si on ne bouge pas regulierement la souris par exemple ! Il semble y avoir un temps minimum de latence par defaut !?
Programme (corps des processus legers) :
class Mon_processus3
extends Thread
{ private StringBuffer mon_nom ; priorite mon_pere ; // on a besoin d'une reference de l'applet pour ecrire int mon_numero ; boolean ok ; // va servir a bloquer le processus avant de lancer le traitement Mon_processus3(priorite pere, String nom, int num) { super() ; ok = false ; mon_numero = num ; mon_nom = new StringBuffer(nom) ; mon_pere = pere ; } // run est le corps du processus public void run() { while (! ok) // attente bloquante pour laisser la main a l'applet { try { sleep(50) ; } catch (InterruptedException e) {} } while (true) { if (mon_pere.sema) { mon_pere.met_semaphore() ; try { sleep(1000) ; } catch (InterruptedException e) {} mon_pere.qui_est_actif(mon_nom, mon_numero) ; } yield() ; } // boucle infinie } public void dit_ok() { ok = true ; } public void desactive() { ok = false ; } } |
Programme (modifications de l'applet) :
import java.applet.* ;
import java.awt.*; public class priorite extends Applet //implements Runnable { final int NB_PROC=5 ; protected Mon_processus3[] p ; protected int combien, ligne, num_actif, total ; protected StringBuffer message ; protected Graphics gc ; protected boolean deja_lance, sema ; .../... public void paint(Graphics g) { int i ; StringBuffer msg ; // efface autoritairement l'ecran g.clearRect(0,0, 500,500) ; g.setColor(Color.black) ; g.drawString(message.toString(), 5, 10) ; total = 0 ; for (i=0 ; i<NB_PROC ; i++) { msg = new StringBuffer("Processus ") ; msg.append(i) ; msg.append(" a la priorite : ") ; msg.append(p[i].getPriority()) ; total += p[i].getPriority() ; if (i==num_actif) gc.setColor(Color.blue) ; else gc.setColor(Color.red) ; g.drawString(msg.toString(), 5, 10*(i+2)) ; } g.setColor(Color.black) ; if (total==NB_PROC) g.drawString("Fin", 5, 10*(i+3)) ; else { g.drawString("Ok", 5, 10*(i+3)) ; ote_semaphore() ; } } public boolean mouseDown(Event evt, int x, int y) { int i ; if (!deja_lance) { for (i=0 ; i<NB_PROC ; i++) p[i].dit_ok() ; // on debloque chaque processus deja_lance=true ; } else paint(gc) ; return(true) ; } private void change_priorite() { // donne une nouvelle priorite au processus actif p[num_actif].setPriority(Thread.MIN_PRIORITY+(int)(Math.random()*(Thread.MAX_PRIORITY-1)) ) ; } public void qui_est_actif(StringBuffer msg, int i) { num_actif = i ; paint(gc) ; change_priorite() ; } public void ote_semaphore() { if (total==NB_PROC) stop() ; else sema=true ; } public void met_semaphore() { sema=false ; } } |
Ph. RIS 1997