skripta dragan milicev programiranje u realnom vremennu c++ uml

243
 Dragan Milićev P P r r o o g g r r a a m m i i r r a a n n  j  j e e  u u  r r e e a a l l n n o o m m  v v r r e e m m e e n n u u  S S k k r r i i  p  p t t a a  Beograd, 2002.

Upload: -

Post on 21-Jul-2015

685 views

Category:

Documents


6 download

TRANSCRIPT

Dragan Miliev

Programiranje u realnom vremenu Skripta

Beograd, 2002.

Programiranje u realnom vremenu

1

SadrajSadraj 1

I C++

OSNOVE OBJEKTNO ORIJENTISANOG PROGRAMIRANJA NA JEZIKU 4Pregled osnovnih koncepata OOP-a na jeziku C++ Klase Konstruktori i destruktori Nasleivanje Polimorfizam Vebe Elementi jezika C++ koji nisu objektno orijentisani Ugraeni tipovi i deklaracije Pokazivai Nizovi Izrazi Naredbe Funkcije Struktura programa Oblast vaenja imena ivotni vek objekata Konverzije tipova Dinamiki objekti Funkcije Operatori i izrazi Vebe Klase i preklapanje operatora Pojam i deklaracija klase Pokaziva this Zajedniki lanovi klasa Prijatelji klasa Konstruktori Destruktor Pojam preklapanja operatora Operatori new i delete Primeri struktura pogodnih za RT implementacije Nasleivanje Izvedene klase Polimorfizam Viestruko nasleivanje 5 5 6 7 8 9 12 12 12 13 14 15 15 16 17 18 20 21 21 24 25 27 27 28 29 30 31 33 33 34 35 58 58 61 66

II

OSNOVE OBJEKTNO ORIJENTISANOG MODELOVANJA NA JEZIKU UML 67Modelovanje strukture Klasa, atributi i operacije Asocijacija 68 68 68

2

Programiranje u realnom vremenuZavisnost Generalizacija/Specijalizacija Interfejsi Modelovanje ponaanja Interakcije i dijagrami interakcije Aktivnosti i dijagrami aktivnosti Maine stanja i dijagrami prelaza stanja Organizacija modela Paketi Dijagrami 71 72 73 74 74 76 78 85 85 85

III UVOD U SISTEME ZA RAD U REALNOM VREMENUDefinicija sistema za rad u realnom vremenu Podela i terminologija RT sistema Primeri RT sistema Karakteristike RT sistema

8687 87 88 89

IV

POUZDANOST I TOLERANCIJA OTKAZAPouzdanost i tolerancija otkaza Pouzdanost, padovi i otkazi Spreavanje i tolerancija otkaza N-Version Programiranje Dinamika softverska redundansa Blokovi oporavka Izuzeci i njihova obrada Dinamika redundansa i izuzeci Obrada izuzetaka bez posebne jezike podrke Izuzeci i njihova reprezentacija Obrada izuzetka Propagacija izuzetka Vebe

9091 91 92 93 95 98 101 101 101 102 104 106 107

V

OSNOVE KONKURENTNOG PROGRAMIRANJAKonkurentnost i procesi Konkurentno programiranje Pojam procesa Predstavljanje procesa Interakcija izmeu procesa Implementacija niti Vebe Sinhronizacija i komunikacija pomou deljene promenljive Meusobno iskljuenje i uslovna sinhronizacija Uposleno ekanje Semafori Uslovni kritini regioni Monitori Klasifikacija poziva operacija Implementacija sinhronizacionih primitiva Vebe

110111 111 113 114 117 118 136 138 138 140 143 148 149 155 155 160

Programiranje u realnom vremenuSinhronizacija i komunikacija pomou poruka Sinhronizacija procesa Imenovanje procesa i struktura poruke Randevu u jeziku Ada Komunikacija u metodi ROOM Vebe Kontrola resursa Modeli za pristup deljenim resursima Problemi nadmetanja za deljene resurse Vebe 163 163 165 166 169 170 171 171 173 180

3

VI

SPECIFINOSTI RT PROGRAMIRANJARealno vreme asovnik realnog vremena Merenje proteklog vremena Vremenske kontrole Kanjenje procesa Specifikacija vremenskih zahteva Kontrola zadovoljenja vremenskih zahteva Implementacija u kolskom Jezgru Vebe Rasporeivanje Osnovne strategije rasporeivanja Testovi rasporedivosti Optiji model procesa Projektovanje prema vremenskim zahtevima Vebe

182183 183 186 187 191 192 196 198 208 217 217 221 227 234 238

4

Programiranje u realnom vremenu

I

Osnove objektno orijentisanog programiranja na jeziku C++

Programiranje u realnom vremenu

5

Pregled osnovnih koncepata OOP-a na jeziku C++U ovoj glavi bie dat kratak i sasvim povran pregled osnovnih koncepata OOP koje podrava C++. Potpunija i preciznija objanjenja koncepata bie data kasnije, u posebnim glavama. Primeri koji se koriste u ovoj glavi samo su pokazni, nisu pravljeni da budu upotrebljivi. Iz realizacije primera izbaeno je sve to bi smanjivalo preglednost osnovnih ideja. Zato su primeri esto i nekompletni. italac ne treba da se trudi da posle itanja ove glave zapamti sintaksu reenja, niti da otkrije sve pojedinosti pokazanih primera. Cilj je da italac samo stekne predstavu o osnovnim idejama OOP-a i jezika C++, da vidi ta je novo i ta se sve moe uraditi, kao i da naui da razmilja na novi, objektni nain.

KlaseKlasa (engl. class) je osnovna organizaciona jedinica programa u OOP jezicima, pa i u jeziku C++. Klasa predstavlja strukturu u koju su grupisani podaci i funkcije:// Deklaracija klase: class Osoba { public: void koSi(); private: char* ime; int god; };

// funkcija: predstavi se! // ... i jo neto // podatak: ime i prezime // podatak: koliko ima godina

// Svaka funkcija se mora i definisati: void Osoba::koSi () { coutnext=e->next; else head=e->next; if (internalIterator && internalIterator->currentItem()==e->cont) internalIterator->next(); delete e; sz--; } void Collection::append (Object* e) { if (head==0) head=tail=new CollectionElement(e); else tail=new CollectionElement(e,tail,0); sz++; } void Collection::insert (Object* e, int at) { if (atsize()) return; if (at==0) { head=new CollectionElement(e,head); if (tail==0) tail=head; sz++; return; } if (at==size()) { append(e); return; } int i=0; for (CollectionElement* cur=head; inext, i++); new CollectionElement(e,cur->prev,cur); sz++; } void Collection::remove (Object* e) { if (tail && tail->cont==e) { remove(tail); return; } for (CollectionElement* cur=head; cur!=0; cur=cur->next) if (cur->cont==e) remove(cur); } Object* Collection::remove (int at) { Object* ret = 0; if (at=size()) return 0; if (at==0) { ret = head->cont; remove(head);

Programiranje u realnom vremenureturn ret; } if (at==size()-1) { ret = tail->cont; remove(tail); return ret; } int i=0; for (CollectionElement* cur=head; inext, i++); ret = cur->cont; remove(cur); return ret;

39

}

void Collection::clear () { for (CollectionElement* cur=head, *temp=0; cur!=0; cur=temp) { temp=cur->next; delete cur; } head=0; tail=0; sz=0; if (internalIterator) internalIterator->reset(); } Object* Collection::first () { if (head==0) return 0; else return head->cont; } Object* Collection::last () { if (tail==0) return 0; else return tail->cont; } Object* Collection::itemAt (int at) { if (at=size()) return 0; int i=0; for (CollectionElement* cur=head; inext, i++); return cur->cont; } int Collection::location (Object* e) { int i=0; for (CollectionElement* cur=head; cur!=0; cur=cur->next, i++) if (cur->cont==e) return i; return -1; } CollectionIterator* Collection::createIterator () { return new CollectionIterator(this); }

///////////////////////////////////////////////////////////////////// // class CollectionIterator /////////////////////////////////////////////////////////////////////

40

Programiranje u realnom vremenu

int CollectionIterator::next () { if (cur!=0) cur=cur->next; return !isDone(); } Object* CollectionIterator::currentItem () { return cur?cur->cont:0; }

Primer upotrebe#include "collection.h" #include class Object { //... }; class X : public Object { public: X(int ii) : i(ii) {} int i; //... }; void main () { X* x1 = new X* x2 = new X* x3 = new X* x4 = new X* x5 = new

X(1); X(2); X(3); X(4); X(5);

Collection* col1 = new Collection; col1->append(x1); col1->append(x2); col1->insert(x3); col1->insert(x4,2); X* x = (X*)col1->removeFirst(); col1->append(x); col1->insert(x5,3); CollectionIterator* it = col1->getIterator(); for (it->reset(); !it->isDone(); it->next()) { X* x = (X*)it->currentItem(); coutappend(x5); it = col2->getIterator(); for (it->reset(); !it->isDone(); it->next()) { X* x = (X*)it->currentItem(); coutcurrentItem(); coutisDone(); it->next()) { X* x = (X*)it->currentItem(); couthead; } { if (cur!=0) cur=cur->next; return !isDone(); }

isDone() { return cur==0; } currentItem() { return cur?cur->getHolder():0; } currentElement() { return cur; }

Object* CollectionElement* private:

Collection* col; CollectionElement* cur; }; #endif // // // // // // // // // // Project: Real-Time Programming Subject: Data Structures Module: Collection File: collect.cpp Date: October 2002 Author: Dragan Milicev Contents: Class: CollectionElement Collection CollectionIterator

Programiranje u realnom vremenu#include "collect.h" ///////////////////////////////////////////////////////////////////// // class Collection ///////////////////////////////////////////////////////////////////// Collection::Collection () : head(0), tail(0), sz(0), internalIterator(new CollectionIterator(this)) {} Collection::~Collection () { clear(); delete internalIterator; } void Collection::append (CollectionElement* e) { if (e==0 || e->getContainer()!=0) return; if (head==0) { e->set(0,0); head=tail=e; } else { e->set(tail,0); tail=e; } e->setContainer(this); sz++; } void Collection::insert (CollectionElement* e, int at) { if (e==0 || e->getContainer()!=0 || atsize()) return; if (at==0) { e->set(0,head); e->setContainer(this); head=e; if (tail==0) tail=head; sz++; return; } if (at==size()) { append(e); return; } int i=0; for (CollectionElement* cur=head; inext, i++); e->set(cur->prev,cur); e->setContainer(this); sz++; } void Collection::insertBefore (CollectionElement* newElem, CollectionElement* beforeThis) { if (newElem==0 || newElem->getContainer()!=0) return; if (beforeThis==0) { append(newElem); return; } if (beforeThis->prev==0) { insert(newElem); return; } newElem->set(beforeThis->prev,beforeThis); newElem->setContainer(this); sz++;

45

46}

Programiranje u realnom vremenu

void Collection::insertAfter (CollectionElement* newElem, CollectionElement* afterThis) { if (newElem==0 || newElem->getContainer()!=0) return; if (afterThis==0) { insert(newElem); return; } if (afterThis->next==0) { append(newElem); return; } newElem->set(afterThis,afterThis->next); newElem->setContainer(this); sz++; } void Collection::remove (CollectionElement* e) { if (e==0 || e->getContainer()!=this) return; if (e->next!=0) e->next->prev=e->prev; else tail=e->prev; if (e->prev!=0) e->prev->next=e->next; else head=e->next; e->set(0,0); e->setContainer(0); if (internalIterator && internalIterator->currentItem()==e->getHolder()) internalIterator->next(); sz--; } Object* Collection::remove (int at) { CollectionElement* ret = 0; if (at=size()) return 0; if (at==0) { ret = head; remove(head); return ret?ret->getHolder():0; } if (at==size()-1) { ret = tail; remove(tail); return ret?ret->getHolder():0; } int i=0; for (CollectionElement* cur=head; inext, i++); ret = cur; remove(cur); return ret?ret->getHolder():0; } void Collection::clear () { for (CollectionElement* cur=head, *temp=0; cur!=0; cur=temp) { temp=cur->next; cur->set(0,0); cur->setContainer(0); } head=0; tail=0; sz=0; if (internalIterator) internalIterator->reset(); } Object* Collection::itemAt (int at) { if (at=size()) return 0; int i=0;

Programiranje u realnom vremenufor (CollectionElement* cur=head; inext, i++); return cur?cur->getHolder():0;

47

}

int Collection::location (CollectionElement* e) { if (e==0 || e->getContainer()!=this) return -1; int i=0; for (CollectionElement* cur=head; cur!=0; cur=cur->next, i++) if (cur==e) return i; return -1; } CollectionIterator* Collection::createIterator () { return new CollectionIterator(this); }

Primer upotrebe#include "collect.h" #include class Object { //... }; class X : public Object { public: X(int ii) : i(ii), ceForC1(this), ceForC2(this) {} int i; CollectionElement ceForC1; CollectionElement ceForC2; //...

};

void main () { X* x1 = new X* x2 = new X* x3 = new X* x4 = new X* x5 = new

X(1); X(2); X(3); X(4); X(5);

Collection* col1 = new Collection; col1->append(&x1->ceForC1); col1->append(&x2->ceForC1); col1->insert(&x3->ceForC1); col1->insert(&x4->ceForC1,2); X* x = (X*)col1->removeFirst(); col1->append(&x->ceForC1); col1->insert(&x5->ceForC1,3); CollectionIterator* it = col1->getIterator(); for (it->reset(); !it->isDone(); it->next()) { X* x = (X*)it->currentItem(); coutappend(&x3->ceForC2); col2->append(&x4->ceForC2); col2->append(&x5->ceForC2); col2->append(&x3->ceForC1); // Tolerant Error it = col2->getIterator(); for (it->reset(); !it->isDone(); it->next()) { X* x = (X*)it->currentItem(); coutcurrentItem(); coutisDone(); it->next()) { X* x = (X*)it->currentItem(); coutgetContainer()!=this) return; col.remove(e); e->setContainer(0); if (highest!=e) return; Priority maxPri = MinPri; highest = 0; CollectionIterator* it = getIterator(); for (it->reset(); !it->isDone(); it->next()) { PriorityElement* pe = (PriorityElement*)it->currentElement(); if (pe->getPriority()>=maxPri) { maxPri = pe->getPriority(); highest = pe; } }

}

void PriorityQueue::clear () { CollectionIterator* it = getIterator();

Programiranje u realnom vremenufor (it->reset(); !it->isDone(); it->next()) { PriorityElement* pe = (PriorityElement*)it->currentElement(); pe->setContainer(0); } col.clear(); highest = 0;

53

}

void PriorityQueue::notifyPriorityChange (PriorityElement* e) { if (e==0 || e->getContainer()!=this) return; if (highest==0 || highest->getPriority()getPriority()) { highest = e; return; } if (highest==e) { Priority maxPri = e->getPriority(); CollectionIterator* it = getIterator(); for (it->reset(); !it->isDone(); it->next()) { PriorityElement* pe = (PriorityElement*)it>currentElement(); if (pe->getPriority()>maxPri) { maxPri = pe->getPriority(); highest = pe; } } return; } }

Primer upotrebe#include "pqueue.h" #include class Object { //... }; class X : public Object { public: X(int ID, Priority pri) : id(ID), peForPQ(this) { peForPQ.setPriority(pri); } int id; PriorityElement* getPriorityElement () { return &peForPQ; } } Priority void getPriority () { return peForPQ.getPriority();

setPriority (Priority pri) { peForPQ.setPriority(pri); }

private: PriorityElement peForPQ; }; //...

void main () { X* x1 = new X(1,1); X* x2 = new X(2,2); X* x3 = new X(3,3);

54

Programiranje u realnom vremenuX* x4 = new X(4,4); X* x5 = new X(5,5); PriorityQueue* pq = new PriorityQueue; pq->add(x1->getPriorityElement()); pq->add(x3->getPriorityElement()); pq->add(x4->getPriorityElement()); pq->add(x2->getPriorityElement()); pq->add(x5->getPriorityElement()); X* top = 0; top = (X*)pq->first(); cout