faculté i&c, claude petitpierre, andré maurer 1 systèmes multi-processus c. petitpierre...
TRANSCRIPT
Faculté I&C, Claude Petitpierre, André Maurer
1
Systèmes multi-processus
C. Petitpierre
25.3.2009
Faculté I&C, Claude Petitpierre, André Maurer
2
Comment simuler un thread en Javascript ?
• En codant les instructions setTimeout judicieusement par soi-même
• En utilisant Synchronous Javascript
Faculté I&C, Claude Petitpierre, André Maurer
3
function execute () { var count = 0 while(true) { count ++ autres activités
delai(1 seconde)
document.getElementById('display').innerHTML = ""+count }}
<body onload='execute()'></body>
Thread : (fil conducteur, fil de l’histoire)
Faculté I&C, Claude Petitpierre, André Maurer
4
Simulation du thread précédentpar découpage en méthodes
var count = 0 // globale
function execute () { count ++ setTimeout(execute2, 1000)}
function execute2 () { document.getElementById('display').innerHTML = ""+count setTimeout(execute, 0)}
Faculté I&C, Claude Petitpierre, André Maurer
5
var state = 0var count
function execute () { var delai = 0 switch (state) { case 0: count = 0 state = 1 break; case 1: count ++ state = 2 delai = 1000 break case 2: document.getElementById('display').innerHTML = ""+count state = 1 break } setTimeout(execute, delai)}
Simulation de threadpar les cas d’un switch
Faculté I&C, Claude Petitpierre, André Maurer
6
function execute () . . . case 3:
semaphore = execute state = 1 return // évite son propre setTimeout ci-dessous } setTimeout(execute, delai)}
function execute2 () // relance execute si elle est en attente if (semaphore != null) {
setTimeout(semaphore,0) semaphore = null} }
Synchronisation entre fils d’exécution
Suspension
Relance
Faculté I&C, Claude Petitpierre, André Maurer
7
Synchronisation primaire entre threads
thread 1 thread 2
Suspendre
Relancer
En général, si Relancer est exécuté avant Suspendre, Relancer n’a pas d’effet.
Faculté I&C, Claude Petitpierre, André Maurer
8
Synchronisation avec mémorisationthread 1 thread 2
n
incNWait () { if (n<=0) suspendre n-- } decNResume () { n++ relancer }
n mémorise les signaux envoyés par le relanceur. Il ne faut pas qu’il y ait unchangement de contexte entre le test et suspendre! si n < 0 |n| attentes.
Faculté I&C, Claude Petitpierre, André Maurer
9
Attente dans un processus
function execute () { switch (state) { case 0: . . . state = 1 setTimeout(execute) break; case 1: if (n<=0) { state = 2 semaphore = execute return } else { n-- state = 3 setTimeout(execute) } break case 2: n-- state = 3 setTimeout(execute) break} }
Faculté I&C, Claude Petitpierre, André Maurer
10
function execute () { switch (state) { case 1: init case 2: if (test) { corps; setTimeout(execute, 1000) action state = 2 } else { setTimeout(execute) state = 3 } break case 3: . . . break} }
for (init; test; action) { corps }
corps contient un délai
Attente dans une boucle for
Faculté I&C, Claude Petitpierre, André Maurer
11
Création et appel d’un objet (actif ou passif)
function send (msg) { .... }
function run() { …]
Ox = new Object()
Ox.send (msg);
Object Ox
Faculté I&C, Claude Petitpierre, André Maurer
12
Objet actif = protection + activité
function send (msg) { .......... }
function run() { . . .}
obj
obj.send (msg) ; Objet O2
obj.send (msg) ; Objet O1
obj.send (msg) ; Objet O3
Faculté I&C, Claude Petitpierre, André Maurer
13La méthode send est exécutée pendant le rendez-
vous
frunction send (msg){ .......... }
function run () { . . . accept Send ; . . .}
obj1
function run () {
obj1.end (msg) ;
}rendez-vous
obj2
Faculté I&C, Claude Petitpierre, André Maurer
14
Modélisation par une machine d’états
State1: select {
accept recv; buf.store (message); ||
obj1.send (buf); ||
waituntil (timeoutStart + T1);handleTimeout();
}
obj1.send
accept recv
State1
Faculté I&C, Claude Petitpierre, André Maurer
15
Modélisation des rendez-vous
A
B
C
p
qr
D
E
F
p
sr
AD
BD
CD
q
AE
BE
CE
pp
q
AF
BF
CF
q
s
s
s
Etats atteignables
Faculté I&C, Claude Petitpierre, André Maurer
16
Synchronous Javascript: objet actifprocess Compte (name, periode) { var compte = 0 this.run = function () { // corps du processus for (;;) { // boucle infinie var t = now() + periode waituntil (t) document.getElementById(name).innerHTML = compte++ } }}function execute (arg) { new Compte("compteur1", 3200) new Compte("compteur2", 500)}
Faculté I&C, Claude Petitpierre, André Maurer
17
Deux processus avec synchronisation
process Compte (name, periode) { var compte = 0 this.kick = function () { } this.run = function () { for (;;) { select { case waituntil (now() + periode) case accept kick } document.getElementById(name) .innerHTML = compte++ } }}
var compteur process Start(nom) { var compte = 0 this.run = function () { for (;;) { compteur.kick() waituntil (now() + 1000) document.getElementById(nom) .innerHTML = compte++ } }}
function executeKick (arg) { compteur = new Compte("cpt1", 3200) new Start("cpt2")}
Faculté I&C, Claude Petitpierre, André Maurer
18
Sémaphore habituel(Dijkstra)
process Semaphore(name) { this.p = function () {} this.v = function () {} this.run = function () { for (;;) { accept p accept v } }}
process Task1(name) { this.run = function() { for (;;) { semaphore.p() imprimeLignes() semaphore.v() } }}
process Task2(name) { this.run = function() { for (;;) { semaphore.p() imprimeLignes() semaphore.v() } }} Une seule tâche peut être en train d’imprimer à un moment donné
Faculté I&C, Claude Petitpierre, André Maurer
19
Canal ou boîte-aux-lettresprocess Producer(name) {
this.run = function() { . . . channel.put( m ) . . . }}
process Consumer(name) {
this.run = function() { . . . x = channel.get() . . . }}
if (space available) { accept put} if (data) { accept get }
Faculté I&C, Claude Petitpierre, André Maurer
20
Canal entre threadsprocess Producer(name) { var count = 0 this.run = function() { for (;;) { waituntil(now() + 1000) channel.put(""+count) count += 2 } }}
process Consumer(name) { var x this.run = function() { for (;;) { x = channel.get() display( x )} } }
process Channel(name) { var list = [] this.put = function (data) {list.push(data)} this.get = function () { return list.shift()} this.run = function () { for (;;) { select { case when (list.length>0) accept get case when (list.length<5) accept put } } }}var channel= new Channel("a")
Faculté I&C, Claude Petitpierre, André Maurer
21
Synchronisation avec un bouton
process Periodique(name) {
this.run = function() { . . . button.clicked() . . . }}
process Button(name) { this.clicked = function() { }
this.synchronize = function(data) { if (this.inSyncList) return accept clicked }}// pseudo-processus, pas de run
<button onclick='button.synchronize()'>
bloquant
non bloquant
Faculté I&C, Claude Petitpierre, André Maurer
22
Kernel
Queue des prêts
Queue des synchronisations
onload = "init()"
function init () { new Process("xxx")}
this.run() { switch(state) { case 3: await (accept v, waituntil…) state = 4 return case 4: . . . fil d’exécution} appel de fonction
setTimeout()
Faculté I&C, Claude Petitpierre, André Maurer
23
Synchronisation avec un boutonvar buttonvar periodiqueprocess Periodique(name) { this.go = function () {} this.run = function() { this.count = 0 while(true) { this.count++ select { case waituntil(now()+3000) display(this.count) case button.clicked() } } }}
process Button(name) { this.clicked = function() { } this.synchronize = function(data) { if (this.inSyncList) return accept clicked // non bloquant // parce qu'il est dans this.synchronize } // et non dans run}
<button onclick='button.synchronize()'>
Faculté I&C, Claude Petitpierre, André Maurer
24
Synchronisation avec un bouton(avec passage de données)
var buttonvar periodiqueprocess Periodique(name) { this.go = function () {} this.run = function() { this.count = 0 while(true) { this.count++ select { case waituntil(now()+3000) display(this.count) case button.clicked() } } }}
process Button(name) { this.clicked = function() { } this.data = 0 // optionnel this.synchronize = function(data) { if (this.inSyncList) return this.data = data accept clicked // non bloquant // parce qu'il est dans this.synchronize } // et non dans run}
<button onclick='button.synchronize()'>
Faculté I&C, Claude Petitpierre, André Maurer
25
Exercices
• Créer deux processus qui font bouger des images dans des rectangles, indépendamment l’un de l’autre.
• Introduire des boutons qui appellent chacun une méthode, dans un des processus, qui inverse la vitesse à laquelle l’image progresse.
• Créer un simulateur de files d’attentes, en définissant des sources, des puits et des files d’attente d’événements.