1.05k likes | 1.17k Views
Systeem-ge ï ntegreerde Programmatuur. Marc Gobin (&Yolande Berbers) Departement Computerwetenschappen (200A 03.20) (Yolande@cs.kuleuven.ac.be). practische organisatie. Marc Gobin is ziek ik geef enkele weken les zeker 2, waarschijnlijk 3, misschien meer
E N D
Systeem-geïntegreerde Programmatuur Marc Gobin (&Yolande Berbers) Departement Computerwetenschappen (200A 03.20)(Yolande@cs.kuleuven.ac.be)
practische organisatie • Marc Gobin is ziek • ik geef enkele weken les • zeker 2, waarschijnlijk 3, misschien meer • slides kun je vinden via mijn home-page • http://www.cs.kuleuven.ac.be/~yolande/ • lessen over device drivers • die geef ik al altijd • practica: zie verder
overzicht van de cursus • karakteristieken van real-time systemen • Ada en Java voor real-time en embedded systemen • gelijktijdige processen • het invoeren van tijd • interrupts • device drivers • petri-netten • schedulability • temporele logica
practica • 2 practica • practicum 1 • individueel • schrijven van een programma dat gebruik maakt van gelijktijdige taken • begroot op 10 uur • practicum 2 • in groepjes van 2 • schrijven van pakket voor communicatie tussen 2 pc’s • begroot op 20 uur • er wordt een demo van de 2 practica georganiseerd • timing is afhankelijk van verloop herstel Marc Gobin
concurrent programming: inleiding • concurrent programming = notaties en technieken voor • uitdrukken van potentieel parallellisme • oplossen van synchronisatie en communicatie • concurrent programming biedt • abstractiemechanismen om parallellisme te beschrijven • onafhankelijk van de implementatiedetails • de implementatie van parallellisme • onderwerp van computersystemen (hardware en software) • is onafhankelijk van concurrent programming
proces, controledraad • sequentiële programmeertalen: Pascal, C, Fortran, COBOL • programma’s hebben slechts 1 controledraad (Engels: thread) • ze voeren uit, bevel per bevel, totdat het programma eindigt • het pad door het programma kan variëren al naar gelang de invoer, maar bij gelijke invoer heb je een gelijk pad • ‘concurrent’ programmeertalen (programmeertalen voor gelijklopende onderdelen) bevatten de notie van proces • elke proces heeft (tenminste) 1 controledraad • implementatie van processen: • uitvoering op 1 enkele processor (multiprogrammatie) • uitvoering op multiprocessor (met gedeeld geheugen) • uitvoering op multicomputer (met gescheiden geheugen) • concurrent slaat op potentieel parallellisme
niet bestaand gecreëerd initialiserend beëindigd uitvoerbaar levencyclus van een proces
proces, controledraad • RTSS (run-time support system) • heeft de taak van het creëren en initialiseren van een proces • eventueel ook van het schedulen van de verschillende controledraden • wordt meestal door de compiler gegenereerd • alternatief voor concurrent programmeertalen • gescheiden processen schrijven met een sequentiële taal • de mogelijkheden van het besturingssysteem gebruiken om gelijktijdige uitvoering te bekomen
proces, controledraad • processen • worden voorzien in alle besturingssystemen • elke proces voert uit in een eigen virtuele machine, zonder interferentie van andere processen (logisch gezien alsof ze het enige proces zijn) • controledraden (threads) • soort subproces binnen een klassiek proces • alle controledraden hebben toegang tot gehele virtuele machine • de programmeur en de taal moeten de controledraden voor elkaar beschermen • discussie: op welk niveau moet concurrency aangeboden worden: door de taal of door het besturingssysteem ? • Ada en Java bieden concurrency in de taal • C en C++ niet
proces, controledraad • voordelen van concurrent programmeertalen • beter leesbare en onderhoudbare code • draagbaarder over meerdere besturingssystemen heen • soms is er geen besturingssysteem op een real-time systeem • de compiler kan op een aantal zaken testen • voordelen combinatie sequentiële taal + besturingssyst • gemakkelijker om programma's geschreven in verschillende talen te combineren • op sommige besturingssystemen is het moeilijk om sommige concurrent taalmodellen te implementeren • omdat er standaarden zijn voor besturingssystemen, zijn de programma's draagbaarder
constructies voor concurrent programmeren • 3 fundamentele faciliteiten • uitdrukken van gelijktijdig uitvoeren (door de notie van proces) • synchronisatie tussen processen • communicatie tussen processen • 3 verschillende soorten relaties • onafhankelijk • samenwerkend • in competitie
gelijktijdig uitvoeren • verschillen tussen procesmodellen • structuur • niveau • granulariteit • initialisatie • beëindiging • relaties tussen gecreëerd proces en andere • voorstelling
gelijktijdig uitvoeren • structuur • statisch • aantal processen is vast • dit aantal is gekend tijdens compilatie • dynamisch • aantal processen kan variëren van uitvoering tot uitvoering • niveau • vlak • processen enkel gedefinieerd op hoogste niveau • genest • processen kunnen een hiërarchie vormen: processen kunnen andere processen starten (vader/kind)
gelijktijdig uitvoeren • granulariteit • fijn • het is ‘goedkoop’ om processen te creëren • in een typisch programma worden er veel gecreëerd voor telkens een hele kleine taak • grof • het is ‘duur’ om een proces te creëren • er worden geen grote aantallen processen gecreëerd • initialisatie • parameters doorgeven • expliciete communicatie na creatie
gelijktijdig uitvoeren • beëindiging • beëindigen van de code • door uitvoering van een specifiek ‘zelfmoord’ bevel • expliciete moord door een ander proces • uitvoering van een niet-opgevangen uitzondering • nooit (oneindige lus) • wanneer niet meer nodig (geen communicatie meer mogelijk) • relatie tussen gecreëerd proces en andere • vader/kind: vader (creërend proces) wacht tot het kind gecreëerd en geïnitialiseerd is • hoeder/afhankelijke: hoeder kan niet het blok verlaten waarin de afhankelijke is gecreëerd, voordat de afhankelijke beëindigd is • vader en hoeder kunnen maar hoeven niet zelfde proces te zijn
niet bestaand gecreëerd initialiserend beëindigd wacht opafhank. einde wacht opinit kind uitvoerbaar levencyclus van een proces
gelijktijdig uitvoeren • terminologie bij object-georiënteerde systemen • elke proces is een object (maar niet omgekeerd) • actieve objecten: nemen spontaan acties • reactieve objecten • reageren enkel op invocaties (= operaties die uitgevoerd worden op een object) • bv resources (hulpmiddelen) • passieve objecten • reactieve objecten waarvan de operaties altijd kunnen uitgevoerd worden • beschermde resource: resource beschermd door een passieve entiteit • server: resource waarbij de controle actief is (proces is nodig)
gelijktijdig uitvoeren • voorstelling: 4 basis mechanismen • co-routines • fork/join • cobegin/coend • expliciete procesdeclaratie
procesvoorstelling: co-routines • controle wordt expliciet doorgegeven (sleutelwoord resume): er is geen return-bevel • relatie is symmetrisch • een routine A voert ‘resume B’ uit • routine A stopt uitvoeren • routine B voert uit vanaf het punt waar het vroeger gestopt was • routine A bewaart alle statusinformatie, zodat het later op hetzelfde punt kan verder gezet worden
procesvoorstelling: co-routines Co-routine A Co-routine B Co-routine C 1 2 3 4 5 6 6 resume B resume C resume A 12 7 8 9 13 10 14 resume B resume A resume B 11 15 12 resume C
procesvoorstelling: fork en join • methode: • C := fork F een nieuw proces start de uitvoering van F oproepend proces gaat ook verder • join C; oproepend proces wacht op einde F • gebruikt in POSIX • bij fork kun je parameters doorgeven • met wait wacht je, 1 waarde keert terug • flexibel maar niet erg gestructureerd • geven gemakkelijk aanleiding tot fouten • hoeder moet bijvoorbeeld expliciet wachten op al zijn kinderen
tijdsas procesvoorstelling: fork en join fork fork P F P F join join vaderproces voert join uit voordat kind beëindigd is kindproces heeft gedaan voordat vader join uitvoert
procesvoorstelling: cobegin/coend • na cobegin (of parbegin) staan een aantal blokken die in parallel uitgevoerd worden (ze worden allemaal samen opgestart) • het vaderproces wacht, of voert 1 van de blokken uit • bij coend (of parend) wordt er gewacht tot alle blokken beëindigd zijn
tijdsas procesvoorstelling: cobegin/coend cobegin coend
procesvoorstelling: ex-/impliciete procesdeclaratie • expliciete procesdeclaratie • routines geven tekstueel aan of ze door een apart proces uitgevoerd worden (modula 1) • het is niet meer de oproeper van de routine die aangeeft dat een nieuw proces gecreëerd moet worden • impliciete procesdeclaratie • alle processen die gedeclareerd worden binnen een blok beginnen in parallel uit te voeren bij begin van het blok (Ada)
gelijktijdige uitvoering in Ada • benaming voor sequentieel proces: task • kan gedeclareerd worden • wordt gecreëerd wanneer declaratie zichtbaar wordt: impliciet • procedure eenvoudige_taak eindigt niet voordat task A eindigt procedure eenvoudige_taak is task A; task body A is -- lokale declaraties begin -- bevelen van de taak A end A; begin ... -- taak A begint met uitvoeren voor het eerste bevel in dit blok end eenvoudige_taak;
gelijktijdige uitvoering in Ada • het is mogelijk een task-type te definiëren • maakt het mogelijk om een rij van taken te declareren task type T; type Long is array (1..100) of T; L: Long; task body T is -- lokale declaraties begin -- bevelen van de taak T end T;
gelijktijdige uitvoering in Ada • parameters kunnen doorgegeven worden bij initialisatie procedure Main is type Dimension is (Xplane, Yplane); task type Control (Dim: Dimension); C1: Control(Xplane); C2: Control(Yplane); task body Control is -- lokale declaraties begin -- bevelen van de taak Control (zie in boek) end Control; begin null; end Main;
gelijktijdige uitvoering in Ada • uitzonderingen • bij initialisatie: de creërende taak krijgt de uitzondering ‘Tasking_error’ • tijdens uitvoering: • de nieuwe taak mag de uitzonderingen opvangen • niet opgevangen uitzondering: nieuwe taak wordt beëindigd • beëindiging van een taak • de taak beëindigt zijn uitvoering (normaal of door uitzondering) • de taak voert het bevel ‘terminate’ uit (zie later) • de taak is gestopt door een andere taak (via abort)
gelijktijdige uitvoering in POSIX • twee mechanismen • voor processen • fork() creëert een exacte copie van het oproepende proces • met wait() kan het oproepende proces wachten op het gecreëerde • voor threads • allerhande routines voor creatie en beheer van threads • vaak met veel parameters • nogal complex • beide mechanismen situeren zich op het niveau van het besturingssysteem (zijn dus niet in een taal geïntegreerd)
gelijktijdige uitvoering in POSIX • threads in POSIX • alle threads hebben attributen (vb stack size) • attribute object om deze attributen te manipuleren typedef … pthread_t; typedef … pthread_attr_t; int pthread_attr_init (pthread_attr_t *attr); /* initializes a thread attribute pointed at by attr to default values */ int pthread_setstacksize (pthread_attr_t *attr, size_t stacksize); /* set the stack size of a thread attributed */ int pthread_attr_setstrackaddr (pthread_attr_t *attr, void *stackaddr); /* set the stack address of a thread attribute */
gelijktijdige uitvoering in POSIX • threads in POSIX • alle threads hebben een identifier, uniek in het proces • thread kan deze identifier bekomen via pthread_self typedef … pthread_t; pthread pthread_self (void); /* return the thread_id of the calling thread */ int pthread_equal (pthread_t t1, pthread_t t2); /* compare two thread ids */
gelijktijdige uitvoering in POSIX • threads in POSIX • thread is klaar om uit te voeren na creatie • pthread_create, 4 argumenten: thread identifier, attributes, functie met de code, parameters die doorgegeven moeten worden int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine) (void*), void *arg); /* create a new thread with the given attributes and call the given start_routine with the given argument */
gelijktijdige uitvoering in POSIX • threads in POSIX • thread kan eindigen • door oproep van pthread_exit • bij ontvangst van een signal (zie hoofdstuk 10) • gestopt door pthread_cancel int pthread_exit (void *value_ptr); /* terminate the calling thread and make the pointer value_ptr available to any joining thread */
gelijktijdige uitvoering in POSIX • threads in POSIX • wachten op het einde van een andere thread: pthread_join int pthread_join (pthread_t thread, void **value_ptr); /* suspends the calling thread until the named thread has terminated, and returned values are pointed at by value_ptr */
gelijktijdige uitvoering in POSIX • threads in POSIX • opkuisen na uitvoering en vrijgave van geheugen: • bij join • met detach attribute: geen join nodig int pthread_attr_setdetachstate (pthread_attr_t *attr, int *detachstate); /* set the detach state of the attribute */ int pthread_detach (pthread_t thread); /* the storage space associated with the given thread may be reclaimed when the thread terminates */
een eenvoudig real-time systeem • aflezen van temperatuur en aanpassen van verwarming • aflezen van druk en aanpassen van pomp • telkens de waarden ook op het scherm printen thermokoppel T drukmeter P S pomp verwarming scherm
een eenvoudig real-time systeem • 3 implementatiemethoden • 1 sequentieel programma • houdt geen rekening met het feit dat T, P en S logisch gezien gelijktijdig en onafhankelijk van elkaar zijn • vraagt geen ondersteuning van het run-time- of besturingssysteem • 3 sequentiële programma's • T, P en S zijn geschreven in een sequentiële taal • met primitieven van het besturingssysteem worden 3 processen hiervoor gecreëerd • 1 concurrent programma • T, P en S zijn 3 threads • run-time ondersteuning is nodig
een eenvoudig real-time systeem • 1 sequentieel programma, houdt geen rekening met feit dat T, P en S logisch gezien gelijktijdig en onafhankelijk van elkaar zijn procedure Controller is TR : Temp_Reading; PR : Pressure_Reading; HS : Heater_Setting; PS : Pressure_Setting; begin loop Read(TR); Temp_Convert(TR, HS); Write(HS); Write(TR); Read(PR); Pressure_Convert(PR, PS); Write(PS); Write(PR); end loop; end Controller;
een eenvoudig real-time systeem • 1 sequentieel programma: bespreking • temperatuurmetingen en drukmetingen gebeuren met gelijke intervallen (misschien hoeft dat niet in de praktijk) • mogelijke oplossing: een aantal if-then-else bevelen toevoegen • wanneer het programma bezig is met temperatuur kan er geen aandacht gegeven worden aan de druk en vice-versa • als probleem met lezen van 1 van de 2 metingen blokkeert het geheel (dus ook het deel dat daar niets mee te maken heeft) • mogelijke oplossing: testen of er kan gelezen worden (p. 195) • nadeel is hier wel dat men test via ‘polling’ (busy waiting) • dit vraagt veel processortijd • belangrijkste opmerking: geen weerspiegeling van werkelijkheid, waar temperatuur en druk volledig onafhankelijke subsystemen zijn
een eenvoudig real-time systeem • 3 sequentiële programma's (met primitieven van het besturingssysteem worden 3 processen hiervoor gecreëerd) package Operating_System_Interface is type Thread_Id is private; type Thread is access procedure; functionCreate_Thread (Code: Thread) return Thread_Id; ... end Operating_System_Interface; package processes is procedure Temp_Controller; procedure Pressure_Controller; end processes; package body processes is ...
een eenvoudig real-time systeem • 3 sequentiële programma's (met primitieven van het besturingssysteem worden 3 processen hiervoor gecreëerd) procedure Controller is TC, PS: Thread_Id; begin TC := Create_Thread (Temp_Controller’Access); PC := Create_Thread (Pressure_Controller’Access); end Controller; • bespreking • doordat de taal geen ondersteuning biedt is dit moeilijk te schrijven en te onderhouden (zeker voor grotere systemen) • bv niet erg duidelijk uit de code welke procedures nu gewone zijn en welke bedoeld zijn om als proces uit te voeren
een eenvoudig real-time systeem • 1 concurrent programma waarbij T, P en S 3 threads zijn procedure Controller is taskPressure_Controller; taskTemp_Controller; task body Temp_Controller is begin loop Read(TR); Temp_Convert(TR, HS); Write(HS); Write(TR); end loop; end Temp_Controller ; task body Pressure_Controller is ... begin null; end Controller ;
een eenvoudig real-time systeem • 1 concurrent programma: bespreking • de logica van de toepassing is mooi zichtbaar in de code • dit maakt het geheel leesbaar en onderhoudbaar • probleem dat telkens genegeerd werd: synchronisatie van de data die naar het scherm gestuurd worden (zie hoofdstuk 8)
deel 3concurrent programming:synchronisatie en communicatie met gedeelde variabelen
overzicht • probleemstelling: kritische sectie en conditionele synchronisatie • vb kritische sectie: verhogen van een gedeelde variabele met 1 • vb conditionele synchronisatie: producent/consument met buffer • verondersteld gekend • oplossing 1: busy waiting, suspend/resume: kort • oplossing 2: semaforen • oplossing 3: conditionele kritische secties • oplossing 4: monitors • protected objects: oplossing van Ada
ondersteuning voor semaforen • Ada • geen directe ondersteuning in de taal • gemakkelijk om een package te maken die het aanbiedt voor gebruik tussen taken • 8.4.5: klassiek voorbeeld van producer/consumer in Ada • C • geen ondersteuning • POSIX • tellende semaforen tussen aparte processen en voor verschillende threads in een proces
POSIX semaphores • standard operations for counting semaphores • initialize, wait, signal typedef … sem_t; int sem_init (sem_t *sem_location, int pshared, unsigned int value); /* initializes the semaphore at location sem_location to value pshared determines if used between processes or threads or only between threads of the same process */ int sem_wait (sem_t *sem_location); /* a standard wait operation on a semaphore */ int sem_post (sem_t *sem_location); /* a standard signal operation on a semaphore */
POSIX semaphores • non-standard operations for counting sem. • non-blocking wait, determining value of sem. int sem_trywait (sem_t *sem_location); /* attempts to decrement the semaphore returns -1 if the call might block the calling process */ int sem_getvalue (sem_t *sem_location, int *value); /* gets the current value of the semaphore to a location pointed at by value */