planen for idag
DESCRIPTION
Planen for idag. Synkronisering: Tidsafhængighed i multiprogrammer Semaforer: Binære semaforer Tælle semaforer … Grænseflader: Hvordan implementeres systemkald. Tidsafhængighed i multiprogrammer. proces læser { do { læslinie(indlinie); memcpy(udlinie, indlinie, 80); - PowerPoint PPT PresentationTRANSCRIPT
Datalogi 1F: Multiprogrammering[2]
1
Planen for idag
• Synkronisering:– Tidsafhængighed i multiprogrammer– Semaforer:
• Binære semaforer• Tælle semaforer• …
• Grænseflader:– Hvordan implementeres systemkald
Datalogi 1F: Multiprogrammering[2]
2
Tidsafhængighed i multiprogrammer
proces læser { do { læslinie(indlinie); memcpy(udlinie, indlinie, 80); } while(TRUE);}
proces skriver { do { udskriv(udlinie); } while(TRUE);}
Inddata: rødbeder snabelsko
Uddata:rødbedersnabelskosnabelskosnabelsko………
Uddata:snabelskosnabelskosnabelskosnabelsko…………
Uddata:rødbelskosnabelskosnabelskosnabelsko………
Datalogi 1F: Multiprogrammering[2]
3
Producent-konsument:nu med tæller
item nextProduced;
while (1) {while (counter == BUFFER_SIZE)
yield(); /* do nothing */
buffer[in] = nextProduced;in = (in + 1) % BUFFER_SIZE;counter++;
}
item nextConsumed;
while (1) {while (counter == 0)
yield(); /* do nothing */
nextConsumed = buffer[out];out = (out + 1) % BUFFER_SIZE;counter--;
}
Datalogi 1F: Multiprogrammering[2]
4
Opdatering af delt lager
• Ændringerne af counter skal ske udeleligt (uden afbrydelser)
• Kaldes også atomisk• counter opdatering optræder som én
operation på højniveau sprogniveau
• MEN ikke nødvendigvis i den eksekverbare kode
Datalogi 1F: Multiprogrammering[2]
5
Tælleropdateringer på assemblerniveau
• “counter--” kan være implementeret som:
register1 = counterregister1 = register1 – 1counter = register1
• “counter++” kan være implementeret som:
register2 = counterregister2 = register2 + 1counter = register2
• Ved processkift kan de to operationer sammenflettes
Datalogi 1F: Multiprogrammering[2]
6
Sammenfletning af tælleropdateringer
• Antag at counter har værdien 5. En sammenfletning af assemblerinstruktionerne for producent og konsument kunne være:
konsument: register1 = counter (register1 = 5)konsument: register1 = register1 – 1 (register1 = 4)producent: register2 = counter (register2 = 5)producent: register2 = register2 + 1 (register2 = 6)producent: counter = register2 (counter = 6)konsument: counter = register1 (counter = 4)
• Værdien af count kan være enten 4, 5 eller 6, men den tiltænkte værdi er 5.
Datalogi 1F: Multiprogrammering[2]
7
Datakapløb• Datakapløb opstår, når resultatet af et
multiprogram afhænger af afviklingsrækkefølgen af processerne i multiprogrammet
• Opdateringer til delt lager skal foregå udeleligt:– Kritisk region sikrer det
• Men det kan også være nødvendigt at synkronisere udførselshastigheden af de forskellige processer:– eks:.: snabelsko, snabelsko, snabelsko
Datalogi 1F: Multiprogrammering[2]
8
Semaforer• Processer kommunikerer ved at sende
signaler til hinanden• Dijkstra foreslog semaforer:
– Variable der tæller antallet af gange et signal er sendt men ikke modtaget (den optræder som buffer)
– Operationen signaler(semafor) der sender et signal til semafor
– Operationen vent(semafor), der venter på et signal (hvis intet signal er bufret, sættes processen til at vente)
• Buffer- og ventemekanismerne gør synkroniseringen tidsuafhængig
Datalogi 1F: Multiprogrammering[2]
9
Semaforer: forhold
• Semaforer skal udføres udeleligt:– Atomiske maskinkodeoperationer:
• test and set
– Implementeret i kerne:• Beskyttet mod afbrydelser (swpipl)
• Aktiv venten kan undgås idet en proces kan suspenderes mens den venter
• FIFO ventemekanisme kan forhindre udsultning
Datalogi 1F: Multiprogrammering[2]
10
Forskellige slags semaforer
• I dag findes et utal af semafortyper:– Binære semaforer– Tællesemaforer (Dijkstra’s oprindelige ide)– Beskedsemaforer– Postkassesemaforer– Trafiklyssemaforer
Datalogi 1F: Multiprogrammering[2]
11
Binær semafor: tilstandeClass BinærSem { enum Tilstand {åben, låst} tilstand; kø prockø; int ventende; public: void BinærSem(Tilstand t=åben) { tilstand = t; ventende = 0; } void vent(); void signaler();};
Datalogi 1F: Multiprogrammering[2]
12
Binære semafore: operationervoid BinærSem::vent(){ if(tilstand==åben) tilstand=låst; else { ventende++; <blokér proces>; }}
void BinærSem::signaler(){ if(tilstand==låst) if(ventende > 0) { <aktiver proces>; ventende--; } else tilstand=åben;}
Datalogi 1F: Multiprogrammering[2]
13
Binære semaforer:anvendelse
• Sikring af udelelig adgang til delt data:– Binær semafor hedder ofte MUTEX (mutual
exclusion)– Som eksempel: læser og skriver processerne
fra slide 1
Datalogi 1F: Multiprogrammering[2]
14
skriver
skrevet
læst
læser
Binær semafor: eksempelproces læser { do { læslinie(indlinie); vent(skrevet); memcpy(udlinie, indlinie, 80); signaler(læst); } while(TRUE);}
proces skriver { do { vent(læst); udskriv(udlinie); signaler(skrevet); } while(TRUE);}
læser
klar
læser
skriver
Datalogi 1F: Multiprogrammering[2]
15
Tællesemafor: tilstandclass TælleSem { int tæller; kø prockø; int ventende; public: void TælleSem(int c) { tæller = c; ventende = 0; } void vent(); void signaler();};
Datalogi 1F: Multiprogrammering[2]
16
Tællesemafor: operationer
void TælleSem::vent() {
if(tæller > 0)
tæller--;
else {
ventende++;
<bloker proces>;
}
}
void TælleSem::signaler() {
if(ventende > 0) {
<aktiver proces>;
ventende--;
} else
tæller++;
}
Datalogi 1F: Multiprogrammering[2]
17
Tællesemafor: anvendelse• Administration af en samling ens
ressourcer:– Frekvensbånd ved trådløs transmission– Jobskedulering på klyngecomputer– Uddeling af buffere
• Begrænsning af antallet af aktive processer i en region:– Begrænsning af
multiprogrammeringsgraden i en applikation
Datalogi 1F: Multiprogrammering[2]
18
Beskedsemafor: tilstandclass BeskedSem {
kø bufkø;kø prockø;int ventende;
public:void BeskedSem() { ventende = 0;}buf *vent();void signaler(buf *);
};
Datalogi 1F: Multiprogrammering[2]
19
Beskedsemafor: operationer
buf *BeskesSem::vent() { if(!bufkø.tom()) return bufkø.frigiv(); else { ventende++; <bloker proces>; }}
void BeskedSem::signaler(buf *buffer) { if(ventende > 0) { aflever(buf); <aktiver proces>; ventende--; } else bufkø.tilkø(buf);}
Datalogi 1F: Multiprogrammering[2]
20
Beskedsemafor: anvendelse
• Udveksling af data mellem processer, f.eks. producent-konsument forhold:– To beskedsemaforer:
• FRIE: indeholder frie elementer• FULDE: indeholder fulde elementer
– Producent:• Venter på frie elementer og signalerer med
fulde elementer
– Konsument:• Venter på fulde og signalerer med frie
Datalogi 1F: Multiprogrammering[2]
21
Producent-konsumentprocess læser {
do {lbuf = FRIE.vent();læslinie(*lbuf);FULDE.signaler(lbuf);
} while(TRUE);}
process skriver {do {
sbuf = FULDE.vent();udskriv(*sbuf);FRIE.signaler(sbuf);
} while(TRUE);}
FULDE
FRIE
skriver
læser
buf
buf
buf
buf
for(i=0; i < N; i++) {nbuf = alloker(sizeof(buf));FRIE.signaler(nbuf);
}
buf
buf
Datalogi 1F: Multiprogrammering[2]
22
Postkassesemafor: tilstandclass PostkasseSem {
kø prockø;int ventende;
public:void PostkasseSem() { ventende = 0;}void vent();void signaler();
};
Datalogi 1F: Multiprogrammering[2]
23
Postkassesemafor: operationervoid PostkasseSem::vent() { ventende++; <bloker proces>;}
void PostkasseSem::signaler() { while (ventende > 0) { <aktiver proces>; ventende--; }}
Datalogi 1F: Multiprogrammering[2]
24
Postkassesemafor: anvendelse• En proces kan give en gruppe
processer besked om at en betingelse er opfyldt:– Der er kommet en afbrydelse fra uret– Delt data er blevet opdateret:
• Check om tidsstempel er det samme som sidste gang
• Hvis ja, vent på opdatering
• Uafhængig af antallet af ventende processer
Datalogi 1F: Multiprogrammering[2]
25
Trafiklyssemafor: tilstandclass TrafiklysSem {
enum Farve {rød, grøn} farve;kø prockø;int ventende;
public:void TrafiklysSem (Farve startfarve=grøn)
{ farve = startfarve; ventende = 0;}void vent();void start();void stop();
};
26
Trafiklyssemafor:operationervoid TrafiklysSem::vent() { if(farve==rød) { ventende++; <bloker proces>; }}
void TrafiklysSem::start() { farve=grøn; while(ventende > 0) { <aktiver proces>; ventende--; }}
void TrafiklysSem::stop() { farve=rød;}
Datalogi 1F: Multiprogrammering[2]
27
Trafiklyssemafor: anvendelse• Signal om at en proces/ressource er i
en bestemt tilstand:– Lavprioritetsprocesser har adgang til
netværk udenfor spidsbelastningstidspunkter
• Timerstyret proces starter og stopper• Lavprioritetsprocesser venter
Datalogi 1F: Multiprogrammering[2]
28
Valg af semafortype
• Vi har set at de forskellige semafortyper egner sig til forskellige opgaver
• Skal en kerne understøtte alle semafortyper?
• Ikke nødvendigvis:– Simpel kerne = færre fejl– En given semafor kan bruges til at
konstruere andre semaforer med (dvs. en semafortype er nok)
Datalogi 1F: Multiprogrammering[2]
29
Tællesemafor ud fra binær semafor
?
Datalogi 1F: Multiprogrammering[2]
30
Tællesemafor: tilstandclass TælleSem { int tæller; kø prockø; int ventende; public: void TælleSem(int c) { tæller = c; ventende = 0; } void vent(); void signaler();};
Datalogi 1F: Multiprogrammering[2]
31
Tællesemafor: operationer
void TælleSem::vent() {
if(tæller > 0)
tæller--;
else {
ventende++;
<bloker proces>;
}
}
void TælleSem::signaler() {
if(ventende > 0) {
<aktiver proces>;
ventende--;
} else
tæller++;
}
Datalogi 1F: Multiprogrammering[2]
32
Tællesemafor ud fra binær semafor
• Ide:– Vi skal bruge en kø af ventende processer:
• Dette er allerede understøttet af binære semaforer
– Hvordan ved vi hvor mange signaler, der ikke er modtaget?
• Vi skal bruge en tæller
– Tælleren skal opdateres udeleligt:• vi har brug for en mutex semafor
• Hvordan ser vent og signaler så ud?
Datalogi 1F: Multiprogrammering[2]
33
Tællesemafor: 1. forsøg
void TælleSem::vent() { MUTEX.vent(); if(tæller > 0) tæller--; else { ventende++; KØ.vent(); } MUTEX.signaler();}
void TælleSem::signaler() { MUTEX.vent() if(ventende > 0) { KØ.signaler(); ventende--; } else tæller++; MUTEX.signaler();}
Datalogi 1F: Multiprogrammering[2]
34
Tællesemafor: 2. forsøg
void TælleSem::vent() { MUTEX.vent(); if(tæller > 0) { tæller--; MUTEX.signaler(); } else { ventende++; MUTEX.signaler(); KØ.vent(); }}
void TælleSem::signaler() { MUTEX.vent() if(ventende > 0) { KØ.signaler(); ventende--; } else tæller++; MUTEX.signaler();}
Datalogi 1F: Multiprogrammering[2]
35
Tællesemafor: operationer
void TælleSem::vent() {
KØ.vent();
MUTEX.vent();
tæller--;
if(tæller <> 0)
KØ.signaler();
MUTEX.signaler();
}
void TælleSem::signaler() {MUTEX.vent();
if(tæller == 0) KØ.signaler(); tæller++; MUTEX.signaler();}
Datalogi 1F: Multiprogrammering[2]
36
Grænseflader til kernen
• Kernekald
• Parameteroverførsel
• Repræsentation af ressourcer
Datalogi 1F: Multiprogrammering[2]
37
Kernekald
• Et brugerprogram ønsker at kalde kernefunktionen signal(semafor)
• Hvilken adresse specificeres i den eksekverbare kode i brugerprogrammet?
• Applikationer og kerne udvikles typisk uafhængigt af hinanden
Datalogi 1F: Multiprogrammering[2]
38
Statisk lænkning• Kerne og brugerprogrammer
oversættes hver for sig, men lænkes sammen inden brug:– Kerne og brugerprogrammer startes som et
samlet hele– Kan f.eks. bruges i indlejrede systemer:
• Mobiltelefoner• Vaskemaskiner• Netværksroutere
– Kernekald er blot alm. procedurekald == lave omkostninger
Datalogi 1F: Multiprogrammering[2]
39
Dynamisk lænkning
• Oversættelse af kernen resulterer i en symboltabel, der senere kan anvendes ved oversættelse/lænkning af brugerprogrammer:– Brugerprogrammer skal genlænkes ved
ændringer i kernen
• Dynamic Link Libraries (DLL’er):– Kald sker via en stubprocedure, der finder
den rigtige adresse på køretidspunktet– Stubprocedurer kan evt. overskrives
Datalogi 1F: Multiprogrammering[2]
40
Faste, absolutte adresser
• Hvert kernekald har en fast defineret adresse, der er specificeret i f.eks. en headerfil:– Besværligt at arbejde med for
kerneprogrammører
Datalogi 1F: Multiprogrammering[2]
41
Indirekte kernekald
• De absolutte adresser gemmes i en tabel
• Kernekaldene foretages ved først at slå op i tabellen for at finde adressen på et kernekald:– Tabellens adresse er fast
• Indeks i tabel er kernekaldets identifikation
Datalogi 1F: Multiprogrammering[2]
42
Maskinelstøttede systemkald• I det foregående er det antaget lager er delt
mellem kerne og brugerprogrammer• Dette er sjældent tilfældet:
– Kernen beskyttes via separat adresserum
• Systemkald via speciel maskininstruktion, der samtidig skifter privilegieniveau:– PAL kaldet call_pal PAL_callsys på
alphaerne
• Fungerer typisk som indirekte kernekald, altså via en hoptabel
Datalogi 1F: Multiprogrammering[2]
43
Alpha eksempel
Speficikation af handler:lda a0, syscallHandlerlda a1, 5call_pal PAL_wrent
Foretag et systemkald:lda a0, CALLSYS_WRITEcall_pal PAL_callsys
Specifikation af hoptabel:enum SysCallId {
CALLSYS_WRITE,CALLSYS_READ};
Void (*jumpTable[]) () = {write,read };
Handler:Void syscallHandler
(SysCallId id) {(*jumpTable[id])()}
Datalogi 1F: Multiprogrammering[2]
44
Parameteroverførsel• Parametre overføres via:
– registre (at foretrække):• Alphaerne bruger a0 – a5
– eksplicit i programkoden:• parametrene placeres i den eksekverbare kode efter
kernekaldet• Returadressen skal ændres til at være første instruktion efter
parametrene
• Systemkald indkapsles i køretidsbiblioteker, der bl.a. håndterer typecheck:void writechar(char ch){ callsys (CALLSYS_WRITE, ch); }
Datalogi 1F: Multiprogrammering[2]
45
Parameteroverførsel på Alpha’erne
line: .asciiz ”Skriv mig ud!”
....
lda a0, CALLSYS_WRITE
lda a1, line
call_pal callsys
....
Datalogi 1F: Multiprogrammering[2]
46
Køretidsbiblioteker
• Systemkald indkapsles i køretidsbib-lioteker, der bl.a. håndterer typecheck:
callsys: call_pal PAL_callsys
ret (ra)
unsigned long callsys (SysCallId ...);
void writechar(char ch) {
callsys (SYS_WRITE, ch);
}
Datalogi 1F: Multiprogrammering[2]
47
Kerneressourcer vs. brugerressourcer
• Ved kernekald kan brugerprogrammer overgive brugerressourcer til kernen:– Reference til buffer, der skal udskrives (en adresse
i brugerprogrammets hukommelse og en længde)• Men kernekald opererer også på
systemressourcer, fx: åbne filer, semaforer• Disse systemressourcer skal beskyttes af
kernen, og kan derfor ikke placeres i brugerprogrammernes hukommelse
• Hvordan repræsenteres disse i brugerprogrammet?
Datalogi 1F: Multiprogrammering[2]
48
Håndtag til systemressourcer• Når et brugerprogram reserverer/opretter/får
adgang til en systemressource, modtager den en nøgle (eng.: handle)
• Ved efterfølgende brug af ressourcen præsenteres kernen for nøglen som identifikation
• Afbildningen af nøgler til ressourcer sker per proces, dvs. man kan ikke gætte en anden proces’ nøgler
• Nøgleafbildningen er typisk kædet sammen med proces kontrolblokken
• Nøglen er typisk et heltal
Datalogi 1F: Multiprogrammering[2]
49
Opsummering• Synkronisering af multiprogrammer:
– Udelelige operationer– Forskel på højniveau operationer og
lavniveau– Semaforer
• Generelt synkroniseringsmekanisme• Ingen aktiv venten
• Kernegrænseflade:– Hvordan implementeres systemkald
Datalogi 1F: Multiprogrammering[2]
50
Kilder
• Disse slides er baseret på indholdet af Datalogi 1F kursusbøgerne samt ”Operating System Concepts” 6. udgave