240 likes | 328 Views
Le parallélisme Introduction. Evénement chaînés. onload="f()". f() {. f() {. f() {. setTimeout (f, 100). setTimeout (f, 100). setTimeout (f, 100). }. }. }. Evénement chaînés ( setInterval() ). onload=" setInterval (f, 100)". f() {. f() {. f() {. }. }. }.
E N D
Evénement chaînés onload="f()" f() { f() { f() { setTimeout(f, 100) setTimeout(f, 100) setTimeout(f, 100) } } }
Evénement chaînés(setInterval()) onload="setInterval(f, 100)" f() { f() { f() { } } }
On ne peut pas chaîner les méthodes d’un objet de la même façon moteur Possible this est perdu ! obj = { f : function() { f() { this.x ? this.x setTimeout(this.f, 100) setTimeout(this.f, 100) } } x : 15 } this.f ?
Closures • Le chaînage des appels doit être fait par closure ! • Une closure = une fonction + attributs + son environnement de variables locales • Toute fonction définie à l’intérieur d’une autre fonction produit en fait une closure • Sorte de mini-objet
Closure var x = null function createClosure (arg) { var vLocale = 10 x = function uneClosure(a) { // fonction définie dans alert(vLocale + a + arg) // une autre fonction } } . . . createClosure(45) x(22)
ClosureAutre façon d’y accéder functioncreateClosure(arg) { var vLocale = 10 return function uneClosure(a) { alert(vLocale + a + arg) } } . . . var x = createClosure(45) x(22)
functioncreateClosure(arg) { var vLocale = 10 return function uneClosure(a) { alert(vLocale + a + arg) } } Closure Même après la fin de createClosure, l’environnement contenant les variables locales de cette fonction sont gardées et restent accessibles dans la fonction uneClosure. Si l’on crée deux closures dans la même fonction (même appel), elles partagent le même environnement (qui est celui de la fonction englobante) Si la fonction est définie dans un objet, les attributs de l'objet font partie de la closure
Closure dans un appel à setTimeout functioncreateClosure(arg) { var vLocale = 10 setTimeout( function uneClosure() { alert(vLocale + arg) }, 1000) }
Closure dans un appel à setTimeout functioncreateClosure(arg) { var vLocale = 10 function xxx() { alert(vLocale + arg) } setTimeout( xxx, 1000) }
Animation dans un objet var activeObj = { couleur : "green" run1 : function() {alterneCouleur(this.couleur)varthat = this // that est un nom arbitraire clos = function() { that.run2() }setTimeout( clos, 500) },run2 : function() {alterneCouleur("red")varthat = thissetTimeout( function() { that.run1() }, 500) } }
Une autre possibilitéde définir la séquence var activeObj = {etat : 0, run : function() {switch (etat) { case 0: alterneCouleur("green") etat = 1 break case 1: alterneCouleur("red") etat = 0 break } var that = this setTimeout( function() { that.run() }, 500) } }
Threads La séquence ininterrompue d’appels par timeout constitue le fil (de l’histoire), en anglais thread. Si l’on crée plusieurs objets de ce type, on pourra garder plusieurs fils actifs indépendants. Un thread est un moyen de suivre plusieurs activités sans les mélanger. Ce concept est à la base de la programmation pseudo-parallèle. Java, C++… offrent des moyens pour créer des threads. En C++, ils ne sont pas liés à un objet. Dans ces langages, le fil peut être commuté à tout instant, pas seulement entre les fonctions. Exemple
Au moyen d’un constructeur functionActif() {var etat = 0 varthat = this <<<<<< this.couleur = "green" this.run =function() {switch (etat) { case 0: alterneCouleur("green") etat = 1 break case 1: alterneCouleur("red") etat = 0 break } setTimeout( function() { that.run() }, 500) } }
Extension de Javascript(Compilateur + librairies de LemanOS) process XYZ (nom) { this.run() { for (;;) { waituntil(now() + 2000) } } }
Suspension dans un "thread" process Runner() { this.run = function() { if (x>0) waituntil(now()+10) x = 10 } x=0 } } }
Découpage par le compilateur this.run = function() { this.run = function() { for(;;) { switch(_state) { case 10000:case 10000: if (x>0) { if (!(x>0)) {_state=10002;break} _state = 10001 waituntil(now()+10) setTimeout(that.run, 10) returnreturn case 10001:case 10001: x = 10 x = 10 } case 10002:case 10002: x=0 x = 0 break }} }} compilation
Appel d'un objet avec thread . . . p1 = new XYZ() p1.meth() . . . process XYZ (nom, p1) { this.meth = function() { } this.run() { // boucle infinie for (;;) { . . . acceptmeth } } }
Synchronisation entre objectsrendez-vous process ABC (nom, p1) { this.run() { for (;;) { waituntil(now() + 2000) p1.meth() } } } process XYZ (nom, p1) { this.meth = function() { } this.run() { for (;;) { acceptmeth } } }
Attentes concurrentes this.m1 = function()( { } this.run(nom) { select { case accept m1 case p2.m2() } } this.run(nom) { select { case p1.m1() case p2.m2() } } this.m2 = function()( { } this.run(nom) { select { case accept m2 } } Trois rendez-vous possibles
kernel.js prêts rendez-vous délais
Oiseaux passant par un couloirProgramme process Oiseau() { this.run = function() {for(;;) {// avant le couloir couloir.entrer()// avancer dans le couloir couloir.sortir() // après le couloir } } } process Couloir() { this.entrer() { } this.sortir() { } this.run = function() {for(;;) { accept entrer accept sortir } } }
select avec toutes les possibilités select { case when (i==0) x = proc.meth() x = x + 1 case when (y>0) accept m2 case when (y<0) waituntil(now() + 1000) }
Boîte aux lettres // quoi process Poste(nom) {this.fifo = [ ]this.deposer = function (paquet) {this.fifo.push(paquet) }this.prendre= function () {returnthis.fifo.shift() } . . . // quand . . . this.run = function () {for (;;) {select {caseaccept deposercasewhen (this.fifo.length>0) accept prendre }waituntil(now()+400) } }} Programme 1 Programme 2