1 / 50

Planen for idag

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);

cleta
Download Presentation

Planen for idag

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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); } Inddata: rødbeder snabelsko Uddata: rødbeder snabelsko snabelsko snabelsko ……… Uddata: rødbelsko snabelsko snabelsko snabelsko ……… Uddata: snabelsko snabelsko snabelsko snabelsko ………… proces skriver { do { udskriv(udlinie); } while(TRUE); } Datalogi 1F: Multiprogrammering[2]

  3. 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--; } Producent-konsument:nu med tæller 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 = counter register2 = 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. Class 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(); }; Binær semafor: tilstande Datalogi 1F: Multiprogrammering[2]

  12. void 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; } Binære semafore: operationer 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. proces 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); } skriver læser Binær semafor: eksempel klar skriver læser læser læst skrevet Datalogi 1F: Multiprogrammering[2]

  15. Tællesemafor: tilstand class 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. 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++; } Tællesemafor: operationer 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: tilstand class BeskedSem { kø bufkø; kø prockø; int ventende; public: void BeskedSem() { ventende = 0; } buf *vent(); void signaler(buf *); }; Datalogi 1F: Multiprogrammering[2]

  19. 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); } Beskedsemafor: operationer 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. process 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); } buf buf buf buf buf buf Producent-konsument for(i=0; i < N; i++) { nbuf = alloker(sizeof(buf)); FRIE.signaler(nbuf); } læser FRIE FULDE skriver Datalogi 1F: Multiprogrammering[2]

  22. Postkassesemafor: tilstand class PostkasseSem { kø prockø; int ventende; public: void PostkasseSem() { ventende = 0; } void vent(); void signaler(); }; Datalogi 1F: Multiprogrammering[2]

  23. void PostkasseSem::vent() { ventende++; <bloker proces>; } void PostkasseSem::signaler() { while (ventende > 0) { <aktiver proces>; ventende--; } } Postkassesemafor: operationer 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: tilstand class 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(); }; Datalogi 1F: Multiprogrammering[2]

  26. void TrafiklysSem::vent() { if(farve==rød) { ventende++; <bloker proces>; } } void TrafiklysSem::start() { farve=grøn; while(ventende > 0) { <aktiver proces>; ventende--; } } Trafiklyssemafor:operationer void TrafiklysSem::stop() { farve=rød; }

  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: tilstand class 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. 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++; } Tællesemafor: operationer 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. 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(); } Tællesemafor: 1. forsøg Datalogi 1F: Multiprogrammering[2]

  34. 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(); } Tællesemafor: 2. forsøg Datalogi 1F: Multiprogrammering[2]

  35. 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(); } Tællesemafor: operationer 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 kaldetcall_pal PAL_callsys på alphaerne • Fungerer typisk som indirekte kernekald, altså via en hoptabel Datalogi 1F: Multiprogrammering[2]

  43. Speficikation af handler: lda a0, syscallHandler lda a1, 5 call_pal PAL_wrent Foretag et systemkald: lda a0, CALLSYS_WRITE call_pal PAL_callsys Specifikation af hoptabel: enum SysCallId { CALLSYS_WRITE, CALLSYS_READ}; Void (*jumpTable[]) () = { write, read }; Handler: Void syscallHandler (SysCallId id) { (*jumpTable[id])()} Alpha eksempel 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 Datalogi 1F: Multiprogrammering[2]

More Related