Das Frisör-Problem - Multitasking, Petrinetze und IPC mit Toolbook

Transcription

Das Frisör-Problem - Multitasking, Petrinetze und IPC mit Toolbook
Projektarbeit Sleeping Barber
Inhalt
Inhalt
Inhalt ............................................................................................................ 1
Abbildungsverzeichnis ...................................................................................... 3
Vorwort.......................................................................................................... 4
Ursprüngliches Konzept.................................................................................... 5
Aufgabenstellung.......................................................................................... 5
Werkzeuge .................................................................................................. 5
Gliederung................................................................................................... 5
Startseite.................................................................................................. 6
Intro ........................................................................................................ 6
Textuelle Beschreibung des Problems ........................................................... 6
Aufstellen eines Systemmodells ................................................................... 6
Animiertes Petrinetz ................................................................................... 6
Logisches Programm Pseudocode................................................................. 8
Konkretes Programm mit Animation ............................................................. 8
Extro........................................................................................................ 8
Ablauf ...................................................................................................... 8
Gestaltung ................................................................................................ 9
Inhalt des Intro ....................................................................................... 10
Inhalt der textuellen Beschreibung................................................................ 11
Das Problem des schlafenden Friseurs ........................................................ 11
Inhalt Aufstellen eines Systemmodells/Petrinetz ............................................. 12
Inhalt Pseudocode ...................................................................................... 14
Änderungen am Konzept ................................................................................ 15
Gestaltung ................................................................................................. 15
Intro ......................................................................................................... 15
Aufstellen eines Systemmodells.................................................................... 15
Animiertes Petrinetz.................................................................................... 15
Sonstiges .................................................................................................. 16
Die Programmteile......................................................................................... 17
Intro und Extro als Flash-Animation .............................................................. 17
Einbinden der Flash-Animationen in Toolbook................................................. 18
C-Code...................................................................................................... 22
Behandlung von Windows Ressourcen ........................................................ 23
Barber .................................................................................................... 24
Customer................................................................................................ 27
DLL ........................................................................................................ 29
OpenScript-Code ........................................................................................ 32
Kommunikation Toolbook->Dll .................................................................. 32
Kommunikation Prozesse->Toolbook .......................................................... 33
Windows Botschaften ............................................................................... 33
Animation ............................................................................................... 35
Aufgetretene Probleme................................................................................... 37
Bedienungsanleitung...................................................................................... 40
Anforderungen: .......................................................................................... 40
Installationshinweis: ................................................................................... 40
Bedienung ................................................................................................. 40
Nachtrag ...................................................................................................... 42
Animation .................................................................................................. 42
Miriam Hofmann
Bernd Frick
Seite - 1 -
Projektarbeit Sleeping Barber
Inhalt
WindowsXP ................................................................................................ 45
Blockade ................................................................................................... 46
Setup........................................................................................................ 47
Miriam Hofmann
Bernd Frick
Seite - 2 -
Projektarbeit Sleeping Barber
Abbildungsverzeichnis
Abbildungsverzeichnis
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
Abbildung
1: Petrinetz...................................................................................... 7
2: Grundlayout................................................................................. 9
3: Gestaltungsraster ....................................................................... 15
4: Zeitleiste mit verschiedenen Ebenen ............................................. 17
5: Bibliothek mit den Symbolen von Gampp....................................... 18
6: Symbol "gamp_seite_gehen" ....................................................... 18
7: Toolbook Instructor Catalog ......................................................... 19
8: Eigenschaftsfenster vom Media Player ........................................... 20
9: Object Browser .......................................................................... 20
10: Eigenschaften von Shockwave Flash Object.................................. 21
11: Ein alter Friseur ........................................................................ 22
12: Toolbook fasst zu...................................................................... 37
13: Bedienungsleiste....................................................................... 41
Miriam Hofmann
Bernd Frick
Seite - 3 -
Projektarbeit Sleeping Barber
Vorwort
Vorwort
Danken möchten wir den folgenden Personen, die sich freiwillig uns zur Verfügung
gestellt haben:
Frau Keller, Herr Bernhard, Herr Brümmer, Herr Gampp, Herr Koch, Herr
Mayenberger und Herr Usadel.
Miriam Hofmann
Bernd Frick
Seite - 4 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Ursprüngliches Konzept
Aufgabenstellung
Es
soll
eine
Lern-CD-Rom
erstellt
werden,
die
ein
Problem
der
Interprozesskommunikation beispielhaft behandelt. Am „Problem des schlafenden
Friseurs“ (Sleeping Barber) soll den Studenten vorgeführt werden, welche Probleme
auftreten können und wie diese zu beheben sind.
Hierzu wird das Friseurproblem in ein Petrinetz überführt und die Begriffe
„Transition“ und „Stelle“ eingeführt. Das Petrinetz soll grafisch dargestellt und
animiert sein. Aus dem Petrinetz soll sich Pseudocode und schließlich ein CProgramm ableiten lassen.
Werkzeuge
•
Toolbook
•
Flash
•
Adobe Photoshop
•
Borland C++ Builder
•
Sonstige Grafikwerkzeuge
Gliederung
Die Lern-CD-Rom soll in folgende Kapitel gegliedert werden:
•
Startseite
•
Intro
•
Textuelle Beschreibung des Problems
•
Aufstellen eines Systemmodells
•
Animiertes Petrinetz
•
Logisches Programm, Pseudocode
•
Konkretes Programm
•
Extro
•
Als Erweiterung ist eine Lernzielkontrolle geplant.
Miriam Hofmann
Bernd Frick
Seite - 5 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Startseite
Hier wird der Titel der CD-Rom und die Autoren genannt.
Intro
Das Intro soll eine Einführung in das „Friseurproblem“ geben. Zu sehen sind ein
Friseursalon, ein Friseur, ein Friseurstuhl, 1-7 Kunden und fünf Wartestühle. Die
vorkommenden Personen sollen bekannte Professoren aus der FH sein. Eventuell
werden wir uns auch selbst verewigen. Geplant sind Prof. Koch als Friseur, Prof.
Keller, Usadel, Gampp, Brümmer, Mayenberger, Herr Bernhard als Kunden.
Zuerst wird ein reibungsloser Ablauf dargestellt:
Friseur schläft, Kunde kommt, weckt Friseur, bekommt Haare geschnitten, nächste
Kunden kommen, setzen sich auf Wartestühle bis alle besetzt sind. Wenn kein
Wartestuhl frei ist, gehen die Kunden wieder.
Mit der Zeit verzählt sich der Friseur, d.h. er schläft, obwohl noch ein Kunde da ist.
Der Kunde bewegt sich von Zeit zu Zeit, kratzt sich, bohrt in der Nase, liest.
Koch schnarcht.
Es wird Nacht.
Das Intro kann vom Benutzer abgebrochen werden.
Das Intro soll mit Musik aus Rossinis „Barbier von Sevilla“ unterlegt sein.
Die Figuren sind gezeichnet.
Das Intro wird mit Flash erstellt und in Toolbook durch den universellen Mediaplayer
abgespielt.
Textuelle Beschreibung des Problems
Hier soll der Ablauf und die Problemstellung der Interprozesskommunikation
beispielhaft erklärt werden.
Der Student soll in diesem Abschnitt erfahren, welche Prozesse und Daten anstehen
und wie diese miteinander kommunizieren und auf gemeinsame Daten zugreifen.
Weitere Probleme zum Beispiel die Situation in einer Druckerwarteschlange sollen
herangezogen werden (mit Zeichnung).
Aufstellen eines Systemmodells
Hier
soll
erklärt
werden,
wie
man
praktisch
an
ein
Interprozesskommunikationsproblem herangeht. Es soll Schritt für Schritt ein
Systemmodell erstellt werden.
Animiertes Petrinetz
Aus dem Systemmodell soll ein Petrinetz erstellt werden, dieses soll auch wieder
Schritt für Schritt aufgebaut werden. Die Schaltregeln sollen anhand von
Animationen erläutert werden.
Dabei hat der Benutzer Schalter, um den Friseur und die Kunden zu starten und
Schalter, um den Mutex oder eine der Semaphore durch ein oder mehrere Flag/s zu
ersetzen.
Miriam Hofmann
Bernd Frick
Seite - 6 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Mit den Aktionen des Benutzers werden Prozesse generiert, die tatsächlich
konkurrieren und dies auf der Toolbook-Oberfläche sichtbar machen:
Marken wandern und aktivieren die Transitionen, zu denen sie wandern. Diese
werden entsprechend der Windows-Optik aktiv.
OpenScript teilt hierzu dem globalen Speicher einer Laufzeitbibliothek seine
FensterID mit. Auf Knopfdruck generiert diese Dll dann auch einen Barberprozess,
der seinerseits über Toolbook-eigene Windows-Botschaften Befehle zur Steuerung
der Toolbook-Oberfläche absetzt. So ist es möglich, die einzelnen Prozessphasen in
Echtzeit in Toolbook darzustellen.
Ebenso agieren die Kunden, von denen der Anwender bis zu fünf einzeln starten
kann.
Der Benutzer soll die Möglichkeit haben, fehlerhaften Quelltext (Flags statt
Semaphore, kein Mutex auf Waiting) ablaufen zu lassen. Die Prozesse sollen in
korrekter und fehlerhafter Version mehrfach gestartet werden können.
Abbildung 1: Petrinetz
Miriam Hofmann
Bernd Frick
Seite - 7 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Logisches Programm Pseudocode
Pseudocode mit textuellen Erläuterungen.
Konkretes Programm mit Animation
Darüber hinaus wäre es schön, aber noch ungewiss, wenn es uns gelänge, dass die
tatsächlich ablaufenden konkurrierenden Prozesse auch das Intro steuerten.
Extro
Friseurladen, Nacht, der Kunde ist gegangen.
Herr Bernhard kommt mit Besen kehrt Haare auf, schließt Tür ab, und geht. Koch
schläft immer noch, und schläft und schläft.
Ablauf
Die CD-ROM besteht aus sieben „Kapiteln“, der Benutzer wird linear durch den Inhalt
geführt, hat aber die Möglichkeit über ein Inhaltsverzeichnis gezielt ein Kapitel
auszuwählen.
Das Intro wird am Anfang der CD abgespielt und kann abgebrochen werden. Danach
kann sich der Benutzer alle Kapitel anschauen. Das Extro wird mit der letzten Seite
automatisch abgespielt.
Animationen sind für die Kapitel Intro, Petrinetz, Konkretes Programm und Extro
geplant.
Interaktivität: Petrinetz, Konkretes Programm
Miriam Hofmann
Bernd Frick
Seite - 8 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Gestaltung
Die verschiedenen Kapitelseiten besitzen alle das gleiche Grundlayout, das sieht
folgendermaßen aus:
Oben in der Mitte ist die aktuelle Überschrift des Kapitels, darunter die Seite mit
dem eigentlichen Inhalt.
Im unteren Bereich ist die Navigationsleiste, links und rechts sind Pfeile für die Vorund Zurück-Navigation. Dazwischen sind sieben Buttons mit denen man zu den
einzelnen Anfangskapitelseiten wechseln kann. Die Kapitel werden durch Symbole
repräsentiert, die einerseits in der Überschrift und andererseits auf den Buttons
vorkommen. Sollte ein Kapitel aus mehreren Seiten bestehen wird das im Symbol in
der Überschrift durch aktuelle Seitenzahl/Seitenanzahl angezeigt.
Es wird die Schriftart Verdana benutzt.
Schriftgröße in der Überschrift 22 pkt und im Textblock 16 pkt.
Kapitelüberschrift
Text, Bild, Animation
Zurück
Kap 2
Kap 3
Kap 4
Kap 5
Kap 6
Kap 7
Vor
Abbildung 2: Grundlayout
Auflösung: 1024 x 768
Miriam Hofmann
Bernd Frick
Seite - 9 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Inhalt des Intro
Beschreibung Friseursalon:
Es sind zu sehen
• Friseurstuhl
• Friseur schläft auf Friseurstuhl (schnarcht, kratzt sich, sabbert)
• Frisierwagen mit Werkzeug (Schere, Kamm)
• Fünf Wartestühle
• Tischchen mit Zeitschriften
• Schaufenster mit Aufschrift „Hugo“
• Tür mit Glocke
Der Friseur zählt seine wartenden KundInnen anhand des Klingens der Türglocke.
Denkblasen zeigen seinen Zählerstand an.
Jedes Mal wenn Kunde bezahlt singt Koch: Lalala!
1. Usadel kommt Straße entlang, betritt Laden, Tür macht „Palimpalim“.
Koch wacht durch Türglocke auf (zuckt zusammen), richtet sich.
Denkblase=1
Usadel setzt sich.
Koch fängt an ihn zu rasieren
2. Keller kommt, tritt ein, grüßt, sieht, dass Friseur beschäftigt ist, geht
zur Warteecke, setzt sich, nimmt Zeitschrift und blättert darin.
Denkblase=2
3. Es kommen Mayenberger und gleich dahinter Brümmer, treten
gleichzeitig ein, setzen sich ans andere Ende von den Wartestühlen, sie
plauschen. Türglocke läutet nur einmal. Denkblase=3
4. Usadel ist fertig, bezahlt, geht. Koch singt lalala
5. Koch zählt runter. Denkblase=3-1=2
6. Koch bittet Keller Platz zu nehmen
7. Gampp tritt ein, grüßt, setzt sich, nimmt Zeitschrift und ließt.
Denkblase=3
8. Keller fertig, zahlt, geht
9. Koch zählt, 2
10.Brümmer kommt an die Reihe
11.Brümmer fertig, zahlt, geht
12.Koch zählt, 1
13.Mayenberger bekommt Haare geschnitten
14.Mayenberger fertig, zahlt, geht
15.Koch zählt 0, geht schlafen
16.Gampp langweilt sich, starrt Löcher in die Luft, bastelt Papierflieger,
popelt in der Nase
17.Es wird Nacht
18.Gampp geht
Miriam Hofmann
Bernd Frick
Seite - 10 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Inhalt der textuellen Beschreibung
Das Problem des schlafenden Friseurs
Das Beispiel des schlafenden Friseurs zeigt anschaulich, was passieren kann, wenn
es keinen gegenseitigen Ausschluss durch Semaphoren für die Synchronisation von
Prozessen oder Threads gibt.
Im Intro ist die Türglocke der Zähler, jedes Mal wenn die Tür aufgeht, klingelt die
Türglocke und der Friseur zählt seinen Kundenzähler um eins hoch. Wenn der Friseur
mit einem Haarschnitt bei einem Kunden fertig ist, zählt er seinen Zähler um eins
herunter. Beim Hinausgehen klingelt die Glocke nicht.
Die Fehlerquelle liegt bei der Türglocke, da gleichzeitig mehrere Kunden
hereinkommen können, während die Türglocke nur einmal bimmelt. Um den Fehler
zu verhindern, müsste gewährleistet werden, dass immer nur ein Kunde durch die
Tür kann. In der Interprozesskommunikation wäre diese Schutzmöglichkeit ein
Semaphor.
In der Praxis könnte man das Friseurproblem anhand eines Druckerspoolers
demonstrieren. Jeder Prozess, der eine Datei ausdrucken möchte, muss den Namen
der Datei in ein spezielles Spooler-Verzeichnis schreiben. Der Drucker-Dämon
überprüft periodisch, ob dort auszudruckende Dateien eingetragen worden sind,
druckt sie gegebenenfalls aus und löscht die Namen aus dem Verzeichnis.
Es gibt zwei Variablen, die eine verweist auf den nächsten freien Platz, die andere
auf die nächste zu druckende Datei. Diese beiden Variablen stehen in einer Datei auf
die alle Prozesse zugreifen können.
Nun kann es vorkommen, dass zwei Prozesse mehr oder weniger gleichzeitig eine
Datei ausdrucken möchten. Der Prozess A, der gerade ausgeführt wird, liest die
Variable mit dem nächsten freien Platz und merkt sie sich. Der Prozess A wird
unterbrochen, da seine Prozessorzeit um ist. Das Betriebssystem veranlasst einen
Prozesswechsel zum Prozess B, der auch drucken möchte. Dieser liest ebenfalls die
Variable mit den freien Platz im Verzeichnis, merkt sie sich, schreibt den Dateinamen
an die freie Stelle und erhöht den Wert um 1 (auf den nächsten freien Platz). Seine
restliche Prozessorzeit verwendet er für andere Dinge. Irgendwann wird der Prozess
A, der zuerst drucken wollte, an der Stelle weiter ausgeführt an der er unterbrochen
wurde. Er hat sich die freie Stelle gemerkt und schreibt nun seinen Dateinamen an
diese Stelle, dabei überschreibt er den anderen Dateinamen.
Die Datei vom zweiten Prozess B wird also nie gedruckt.
Dieses Problem kann durch gegenseitigen Ausschluss (Mutual Exclusion) der
Prozesse beim Zugriff auf das Spooler-Verzeichnis umgangen werden.
Miriam Hofmann
Bernd Frick
Seite - 11 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Inhalt Aufstellen eines Systemmodells/Petrinetz
Zwischen konkurrierenden Prozessen kommt es zu Wettkampfbedingungen („race
conditions“) wenn zwei oder mehrere von ihnen gleichzeitig versuchen, auf eine
einzelne Systemressource zuzugreifen. Um die Wettkampfbedingungen in den Griff
zu bekommen, ist es notwendig einen Systementwurf zu machen, der die Vorgänge
in ihrer zeitlichen Abfolge abbilden kann.
Eine Möglichkeit der Darstellung ist die Modellierung als Petrinetz. Petrinetze sind ein
wichtiges Hilfsmittel zur Modellierung nebenläufiger, asynchroner, verteilter oder
paralleler Prozesse.
Ein Petrinetzmodell kennt viererlei Elemente:
Stellen („places“) repräsentieren Bedingungen. Das könnten Zustände,
Signale oder bereitgestellte Daten sein. Auch Stellen mit mehreren Marken
sind möglich und könnten zum Beispiel einen Materialbehälter darstellen.
Bei uns sind es die Signale „Kunde ist da“ oder „Friseur ist bereit“ oder der
Semaphor zum Schutz der Zählvariablen.
Stellen sind im Petrinetz durch einen Kreis symbolisiert.
Transitionen(„transitions“) stehen für Aktionen. Dies können Ereignisse,
Vorgänge oder Berechnungsschritte sein. Im Beispiel sind es die einzelnen
Aktivitäten der Prozesse, also zum Beispiel das Haarschneiden, das
Schlafen und das Warten.
Symbol für eine Transition ist im Petrinetz das Rechteck.
Kanten verbinden Stellen und Transitionen und zeigen damit die Vor- und
Nachbedingungen der Aktionen an und geben damit die Fließrichtung der
Marken vor.
Marken wandern durch das Petrinetz und ermöglichen durch Besetzen der
Stellen die Veränderung der Bedingungen und damit die Ausführung der
Aktionen. Man nennt dies das „Schalten“ der Transitionen. In unserem
Beispiel braucht der Friseur eine Marke um aufzuwachen und die Kunden
je eine um bedient zu werden.
Das Symbol der Marke ist ein gefüllter Kreis.
Miriam Hofmann
Bernd Frick
Seite - 12 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Das Petrinetz ist ein Bedingungs-Ereignisnetz.
Hier gelten die folgenden Regeln:
•
Jedes Petrinetz hat eine Anfangsmarkierung.
•
Transitionen sind im Petrinetz immer über Stellen miteinander verbunden.
•
Eine Transition kann nur schalten, wenn alle nachgeschalteten Stellen frei und
alle vorgelagerten Stellen mit Marken belegt sind.
•
Ausnahmen hiervon sind:
•
Stellen, die gleichzeitig Ein- und Ausgang sind: Durch das Schalten wird hier
die Stelle frei und nach dem Schalten von der gleichen Transition wieder
belegt
•
Transitionen ohne vor- oder nachgelagerte Stellen. Deren Schalten ist nur von
ihrem Aus- bzw. Eingang abhängig.
•
Die Transition verzehrt beim Schalten je eine Marke an allen ihren Eingängen.
•
Bei Beenden ihrer Aktion belegt die Transition alle ihren Ausgangsstellen mit
je einer Marke.
•
Es ist möglich, Konfliktstellen darzustellen, bei denen je nach Ergebnis einer
Bedingungsprüfung die Marke in die eine oder andere Richtung wandert.
•
Miriam Hofmann
Bernd Frick
Seite - 13 -
Projektarbeit Sleeping Barber
Ursprüngliches Konzept
Inhalt Pseudocode
Algorithmus für den Friseur:
Wenn kein Kunde (Kundenzähler = 0) da ist, schlafe. Wenn Türglocke bimmelt,
wache auf und zähle den Kundenzähler um eins hoch und schneide Haare. Wenn
fertig mit Haare schneiden, zähle Kundenzähler um eins herunter. Solange
Kundenzähler nicht Null ist, schneide Haare.
Algorithmus für Kunden:
Wenn Friseur schläft, wecke ihn. Wenn Friseur beschäftigt, warte auf Wartestuhl.
Wenn schon fünf Kunden warten, gehe wieder und komm später wieder.
Eine geeignete Lösung für dieses Problem, ohne dass es unter den einzelnen Kunden
(Threads) zu Wettkampfbedingungen kommt, wäre folgender Pseudocode:
Binary semaphore mutex = 1;
Counting semaphore customers = 0, barber=0;
int waiting = 0;
…
void Barber(void)
{
while(true)
{
P(customers); // wait for or get next customer
P(mutex);
Waiting--;
V(barber);
V(mutex);
Cut_Hair();
}
}
void Customer(void)
{
while(true)
{
P(mutex); //check waiting room
if(waiting < numChairs)
{
waiting++;
V(customers);
V(mutex);
P(barber); //wait for barber
get_hair_cut();
}
else
V(mutex);
}
}
Miriam Hofmann
Bernd Frick
Seite - 14 -
Projektarbeit Sleeping Barber
Änderungen am Konzept
Änderungen am Konzept
Gestaltung
Das Raster wurde auf Grund der Inhalte geändert. Es besteht nun aus vier Blöcken,
die zu je einem drittel Text, Bild oder Animation und zu zwei drittel Text, Bild oder
Animation enthalten.
Kapitelüberschrift
Zurück
Kap 2
Kap 3
Kap 4
Kap 5
Kap 6
Kap 7
Vor
Abbildung 3: Gestaltungsraster
Intro
Das
Intro
wurde
insofern
geändert,
dass
aus
Zeitgründen
kleine
Zwischenanimationen wie „Keller liest“ und „Brümmer und Mayenberger plaudern“
herausgenommen wurden.
Aufstellen eines Systemmodells
Im Kapitel „Aufstellen eines Systemmodells“ kann der Benutzer kleine Animationen
ablaufen lassen, die ihm die Regeln eines Petrinetzes veranschaulichen.
Animiertes Petrinetz
Für das animierte Petrinetz lassen sich Barber- und Customer-Prozesse starten, die
durch ihren Ablauf die Animation steuern.
Miriam Hofmann
Bernd Frick
Seite - 15 -
Projektarbeit Sleeping Barber
Änderungen am Konzept
Sonstiges
•
•
Die Steuerung des eines Filmes durch real ablaufende Prozesse wurde bald
aufgegeben: Ob und wie sich Flash von außen steuern lässt ist ungewiss. Den
Einsatz eines anderen Werkzeuges (Director?) zu evaluieren, fehlte die Zeit.
Der Anwender hat in dieser Version keine Möglichkeit, fehlerhaften Quelltext
ablaufen zu lassen. Prozesse, die ohne Mutex auf das Shared Memory
zugreifen, wurden zwar versuchsweise implementiert, doch erscheint dadurch
ein Fehler in endlicher Zeit nicht provozierbar.
Hierzu müsste auf die Animation verzichtet und die Erzeugung der Customer
automatisiert werden, damit die Prozesse in rascher Folge auf das Shared
Memory zugreifen. Dem Benutzer müsste man dann durch Zählerstände
eventuelle Fehler sichtbar machen, doch wäre immer noch ungewiss, ob und
wann diese eintreten.
Miriam Hofmann
Bernd Frick
Seite - 16 -
Projektarbeit Sleeping Barber
Die Programmteile
Die Programmteile
Intro und Extro als Flash-Animation
Das Intro und Extro wurde in Flash erstellt, da Flash eine komfortable Umgebung
bietet um kleine Animationsfilme zu gestalten.
Die Filme besitzen mehrere Ebenen für Hinter-, Vordergrund, Darsteller und Sounds.
Abbildung 4: Zeitleiste mit verschiedenen Ebenen
Der Hintergrund ist auf die unteren Ebenen verteilt.
Jeder Darsteller besitzt mehrere Ebenen, je nach seiner Position im Film. Wenn er
z.B. von draußen in den Friseurladen kommt, liegt die Darstellerebene unter der
Ebene mit den Wänden. Im Fenster ist der Darsteller sichtbar, da die Fenster einen
Alphawert von 53% besitzen, d.h. alle unter dieser Ebene liegenden Ebenen sind mit
47% sichtbar.
Um die Hauptdarsteller ihren lebenden Vorbildern so ähnlich wie möglich zu
gestalten, wurden die Personen fotografiert und die Fotos eingescannt.
In Flash wurden die Bilder unter die aktuelle Zeichenebene gelegt und abgezeichnet.
Die Ebene mit dem Foto wurde danach wieder gelöscht.
Jede Figur besitzt in der Bibliothek einen eigenen Ordner in denen die jeweiligen
Animationen als Symbole abgelegt werden. Ein Symbol ist eine Animation mit
eigener Zeitleiste. Das Symbol wird in die Szene eingefügt und läuft als Schleife ab.
Zum Beispiel besitzt eine Figur verschieden Laufanimationen, die jeweils aus drei bis
zehn Bildern bestehen. In die Szene eingefügt, wird die Laufanimation bis zum
nächsten Schlüsselbild in Schleife abgespielt.
Um die Figur nicht nur auf der Stelle laufen zu lassen wird in der Szene ein
Bewegungstweening von dem gewünschten Start- bis Endpunkt erzeugt.
Miriam Hofmann
Bernd Frick
Seite - 17 -
Projektarbeit Sleeping Barber
Die Programmteile
Abbildung 5: Bibliothek mit den Symbolen von Gampp
Abbildung 6: Symbol "gamp_seite_gehen"
Einbinden der Flash-Animationen in Toolbook
Das Intro und Extro werden als SWF-Dateien im Toolbook eingebunden.
Im Toolbook Instructor Catalog gibt es unter dem Ordner Media Players einen
Universal Media Player. Dieser wird mit der Maus an die gewünschte Stelle auf der
Oberfläche gezogen.
Miriam Hofmann
Bernd Frick
Seite - 18 -
Projektarbeit Sleeping Barber
Die Programmteile
Abbildung 7: Toolbook Instructor Catalog
Sobald der Mediaplayer losgelassen wird, geht ein Fenster auf. In diesem wird der
Pfad des Flashfilmes angegeben und Autostart aktiviert. D.h. wenn die Seite mit dem
Film aufgerufen wird, wird der Film abgespielt.
Miriam Hofmann
Bernd Frick
Seite - 19 -
Projektarbeit Sleeping Barber
Die Programmteile
Abbildung 8: Eigenschaftsfenster vom Media Player
Im Objekt Browser sieht man, welche Objekte der Universal Media Player besitzt.
Das Objekt „Group media Controls“ bietet die Möglichkeit eine Abspielsteuerung für
den Film einzublenden. Die Objekte „mediaStage“, „OCXArea“ und „ShockwaveFlash“
sollten alle die gleiche Größe und Position besitzen.
Abbildung 9: Object Browser
Im „ShockwaveFlash“-Objekt müssen noch Einstellungen vorgenommen werden:
Miriam Hofmann
Bernd Frick
Seite - 20 -
Projektarbeit Sleeping Barber
Die Programmteile
Abbildung 10: Eigenschaften von Shockwave Flash Object
Bei Qualität, Skalieren, Ausrichten und Fenstermodus kann die Standardeinstellung
übernommen werden. Abspielen muß aktiviert sein, Wiederholung sollte nicht
aktiviert sein, da der Film sonst in einer Schleife abgespielt wird.
Geräteschriftart und Menü brauchen nicht aktiviert zu werden.
Film einbetten sollte aktiviert sein, damit der Film in die Toolbook–Datei
eingebunden wird.
Mit diesen Einstellungen wird der Film abgespielt, wenn die Seite angezeigt wird. Am
Ende des Filmes bleibt der Film auf dem letzten Bild stehen.
Miriam Hofmann
Bernd Frick
Seite - 21 -
Projektarbeit Sleeping Barber
Die Programmteile
C-Code
Zuerst wurden der Barber- und
Customer-Prozesses
als
Windows-Programme mit jeweils
eigenem Fenster unter Borlands
C++ Builder implementiert, um
den Code vor dem Einbau in
Toolbook zu testen und zu
erproben.
Abbildung 11: Ein alter Friseur
Um eine Bedienung mit der Maus
zu ermöglichen, während die Barber- und Customer-Prozesse aktiv sind, wurde die
eigentliche Funktionalität in beiden Prozessen als Thread ausgeführt. Dies bleibt
auch nach deren Anbindung an Toolbook, obwohl hierzu eigentlich keine
Notwendigkeit mehr besteht.
Im nächsten Schritt machten wir uns mit der Toolbook-Umgebung vertraut und
testeten den Aufruf von Funktionen einer Laufzeitbibliothek durch Toolbook und
umgekehrt das Auslösen von Toolbookfunktionalität von ausserhalb.
Schließlich waren die Barber- und Customer-Prozesse sind aus Toolbook heraus
start- und terminierbar.
Im letzten Schritt ersetzten wir die Ausgaben der Borland-Programme durch
Toolbook-Animationen, die von den Prozesse durch das Aussenden von WindowsBotschaften aufgerufen werden.
Miriam Hofmann
Bernd Frick
Seite - 22 -
Projektarbeit Sleeping Barber
Die Programmteile
Behandlung von Windows Ressourcen
Windows stellt die im Projekt verwendeten Systemressourcen binäre Semaphore,
zählend Semaphore und das Shared Memory auf ähnliche Weise zur Verfügung:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
// pointer to
// attributes
BOOL bInitialOwner,
// flag for initial ownership
LPCTSTR lpName
// pointer to mutex-object name
);
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
security
// pointer to security
// attributes
LONG lInitialCount,
// initial count
LONG lMaximumCount,
// maximum count
LPCTSTR lpName
// pointer to semaphore-object name
);
HANDLE CreateFileMapping(
HANDLE hFile,
// handle to file to map
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, //
optional
security
// attributes
DWORD flProtect, // protection for mapping object
DWORD dwMaximumSizeHigh,
// high-order 32 bits of object size
DWORD dwMaximumSizeLow, // low-order 32 bits of object size
LPCTSTR lpName
// name of file-mapping object
);
Durch den Aufruf von CreateMutex() bzw. CreateSemaphore() erzeugt man ein
Semaphorobjekt und erhält ein Handle darauf. Beim Aufruf von CreateSemaphore()
wird außerdem der Wertebereich der zählenden Semaphore und deren Startwert
festgelegt. Der jeweils letzte Parameter gibt der Semaphore einen Namen.
CreateFileMapping() verlangt als ersten Parameter eigentlich einen Handle auf eine
physikalisch vorhandenen Datei. Alternativ kann hier mit dem Parameter
(HANDLE)0xFFFFFFFF ein Pagingfile angegeben sein, dessen Größe dann durch den
fünften Parameter bestimmt sein muss. Mit dem letzten Parameter wird das Objekt
benamst. Auch hier ist es eine einfache Zeichenkette, über die das Shared Memory
systemweit von allen Prozessen angesprochen werden kann.
Vor dem Zugriff auf die Ressourcen müssen sich die Prozesse durch Aufruf der
Funktion OpenSemaphore() einen Handle generieren und diesen nach der Manipulation
der Ressource durch CloseHandle(HANDLE) wieder freigeben.
Wie das im Einzelnen geschieht, sollen die konkreten Vorgänge zeigen.
Miriam Hofmann
Bernd Frick
Seite - 23 -
Projektarbeit Sleeping Barber
Die Programmteile
Barber
Der Barber-Prozess fordert als erstes die benötigten Systemressourcen beim
Betriebssystem an.
TSharedMemory *Msg;// = new TSharedMemory;
hCustomer = CreateSemaphore(NULL, 0, 5, "SemCustomer");
hBarber
= CreateSemaphore(NULL, 0, 1, "SemBarber");
Der zweite Parameter bei der Erzeugung des Mutex-Objektes bedeutet, dass Barber
den Mutex mit der Erzeugung gleich besitzt.
hMutex
= CreateMutex(NULL, TRUE, "Mutex");
hWaiting
= ::CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,PAGE_READWRITE,
0, sizeof(TSharedMemory), "MemWait");
Die Grösse des FileMapping-Objekts ergibt sich aus folgender Struktur:
struct TSharedMemory
{
int Zaehler;
char Zeichen[128];
};
Schließlich öffnet Barber das FileMapping-Objekt für einen schreibenden Zugriff und
initialisiert dessen Zähler:
Msg
=
(TSharedMemory*)::MapViewOfFile(hWaiting,
FILE_MAP_WRITE,
0, sizeof(TSharedMemory));
Msg->Zaehler = 0;
0,
Der Zugriff auf das Shared-Memory wird beendet
::UnmapViewOfFile(Msg);
und der Mutex wieder freigegeben:
ReleaseMutex(hMutex);
Semaphore werden unter Windows durch den Aufruf von ReleaseMutex(HANDLE) bzw.
ReleaseSemaphore(HANDLE) wieder freigegeben.
Barber muss an dieser Stelle die Handles auf die generierten Ressourcen
ausnahmsweise offen halten. Später wird er das nicht mehr tun, denn Handles sind
nach Benutzung gleich wieder zu schliessen.
Allerdings registriert Windows die Anzahl der offenen Handles und entfernt eine
Ressource automatisch, sobald kein Prozess mehr darauf zugreift.
Würde Barber seine Handles hier schon wieder freigeben, würden auch die
neuangelegten Ressourcen wieder aufgegeben.
Miriam Hofmann
Bernd Frick
Seite - 24 -
Projektarbeit Sleeping Barber
Die Programmteile
Barber erzeugt dann ein neues Thread-Objekt und ruft es auf. Die weiteren Aktionen
übernimmt der Thread, doch bleibt sich der Ablauf gleich wie bei einem Prozess ohne
Threads:
BarbThread = new TBarbThread(1);
BarbThread->Resume();
Die
meisten
Systemressourcen
werden
in
Windows
mit
der
Funktion
WaitForSingleObject(HANDLE, time) angefordert, wobei das ‚Object’ ein Semaphor-
oder Mutex-Objekt, aber auch ein Prozesses oder Thread oder ein Timer-Objekt sein
kann. Parameter dieser Funktion ist immer ein Handle auf das Objekte und eine
eventuelle Wartezeit.
Zuerst lief Barber als eigenständiges Windows-Programm. Ein Thread führte die
‚Barber’-Schleife aus, der hiermit vom Hauptprogramm beendet werden konnte:
while(!Terminated)
{
Barber blockiert sich an der Customer-Semaphore:
if(WaitForSingleObject(BarbForm->hCustomer, 100) == WAIT_OBJECT_0)
{
Wenn ein Kunde da ist, schickt Barber Nachrichten an Toolbook (dies später
ausführlich):
SendTBMessage(WacheAuf);
SendTBMessage(BHoleMutex);
Barber verschafft sich wieder ein Handle auf das Mutex-Objekt:
hMutex = OpenMutex(MUTEX_ALL_ACCESS|SYNCHRONIZE, 0, "Mutex");
if(hMutex != NULL)
{
und blockiert bis er den Mutex hat:
if((WaitForSingleObject(hMutex, INFINITE))== WAIT_OBJECT_0)
{
TSharedMemory *Msg;
Ein Handle auf das SharedMemory:
hWaiting = ::OpenFileMapping(FILE_MAP_WRITE, 0, "MemWait");
if (hWaiting)
{
Öffnen des SharedMemory und Erniedrigen des Zählers ‚Waiting’:
Msg
=
(TSharedMemory*)::MapViewOfFile(hWaiting,FILE_MAP_WRITE,
0, 0, sizeof(TSharedMemory));
Msg->Zaehler --;
SendTBMessage(BWaiting);
Miriam Hofmann
Bernd Frick
Seite - 25 -
Projektarbeit Sleeping Barber
Die Programmteile
Schließen des SharedMemory, Handle freigeben und Mutex freigeben:
::UnmapViewOfFile(Msg);
::CloseHandle(hWaiting);
ReleaseMutex(hMutex);
}
}
}
SendTBMessage(BGebeMutex);
Schließlich die Barber-Semaphore erhöhen und frisieren:
ReleaseSemaphore(BarbForm->hBarber, 1, NULL);
SendTBMessage(ErhoeheBarber);
SendTBMessage(Schneide);
SendTBMessage(Schlafe);
}
}
}
Abgesehen von den Messages an Toolbook entspricht dies genau dem Pseudocode in
Tanenbaums Buch. Genauso einfach sind die Dinge beim Customer-Prozess.
Miriam Hofmann
Bernd Frick
Seite - 26 -
Projektarbeit Sleeping Barber
Die Programmteile
Customer
Aus Gründen der Handhabbarkeit erhielt auch der Customer-Prozess einen Thread.
Die Grundfunktionalität ändert sich dadurch aber nicht.
Customer prüft als erstes die Anzahl der bereits wartenden Prozesse. Hierzu braucht
er den Mutex auf das Shared Memory. Diesen kann er einfach über den von Barber
vergebenen Namen ansprechen:
Handle au Mutex herstellen:
hMutex = OpenMutex(MUTEX_ALL_ACCESS|SYNCHRONIZE, 0, "Mutex");
if(hMutex != NULL)
{
Auf Mutex warten:
if((WaitForSingleObject(hMutex, INFINITE))== WAIT_OBJECT_0)
{
TSharedMemory *Msg;
SharedMemory zum Schreiben öffnen:
hWaiting = ::OpenFileMapping(FILE_MAP_WRITE, 0, "MemWait");
if (hWaiting)
{
Msg = (TSharedMemory*)::MapViewOfFile(hWaiting,FILE_MAP_WRITE, 0,
0, sizeof(TSharedMemory));
Zähler prüfen, gegebenenfalls erhöhen:
if(Msg->Zaehler < 5)
{
Msg->Zaehler++;
SendTBMessage(CWaiting);
::UnmapViewOfFile(Msg);
::CloseHandle(hWaiting);
ReleaseMutex(hMutex);
SendTBMessage(CGebeMutex);
Thread erzeugen:
aCustThread = new CustThread(1);
}
Oder terminieren:
else
{
::UnmapViewOfFile(Msg);
::CloseHandle(hWaiting);
ReleaseMutex(hMutex);
SendTBMessage(CCancle);
Application->Terminate();
}
}//hWaiting
}//waitfor
}
Miriam Hofmann
Bernd Frick
Seite - 27 -
Projektarbeit Sleeping Barber
Die Programmteile
Für den Fall, dass Barber noch nicht gestartet ist, war das folgende implementiert.
Für den Start aus Toolbook heraus wird dies nicht mehr benötigt:
else
{
MessageDlg("No Barber", mtError, TMsgDlgButtons() << mbOK, 0);
MessageDlg("No Way", mtError, TMsgDlgButtons() << mbOK, 0);
Application->Terminate();
}
}//if mutex
Der Thread des Customer führt folgenden Code aus:
void __fastcall CustThread::Execute()
{
SendTBMessage(ErhoeheCustomer);
Handle auf eigene zählende Semaphore herstellen:
hCustomer = OpenSemaphore(SEMAPHORE_MODIFY_STATE, false, "SemCustomer");
Diese erhöhen und Handle darauf wieder schließen:
ReleaseSemaphore(hCustomer, 1, NULL);
CloseHandle(hCustomer);
Handle auf Barber-Semaphore generieren:
hBarber = OpenSemaphore(SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, false,
"SemBarber");
if(NULL != hBarber)
{
SendTBMessage(Warte);
An Barber-Semaphore
terminieren:
blockieren
und
auf
Haarschnitt
warten,
schließlich
if((WaitForSingleObject(hBarber, INFINITE))== WAIT_OBJECT_0)
{
CloseHandle(hBarber);
SendTBMessage(Haarschnitt);
SendTBMessage(Gehe);
Terminate();
}
}
}
Die SendTBMessage()-Funktionen sind im Abschnitt „Kommunikation“ eingehend
erläutert.
Miriam Hofmann
Bernd Frick
Seite - 28 -
Projektarbeit Sleeping Barber
Die Programmteile
DLL
Beide Programme sollten zum einen aus Toolbook heraus gestartet werden können
und zum anderen deren Aktionen in Toolbook sichtbar sein. Open Script kann hierzu
einerseits die Funktionen einer DLL benutze, andererseits kann Toolbook über
Windows-Nachrichten von Prozessen angesprochen werden. Diese benötigen hierzu
den Fenster-Handle von Toolbook. Die DLL sollte also folgendes leisten:
•
•
•
Anlage eines Shared Memory, um das Handle des Toolbook-Fensters
abspeichern zu können
Funktionen in das Shared Memory zu schreiben und daraus lesen zu können
Funktionen um die einzelnen Prozesse zu starten und zu beenden
Jeder aufrufende Prozess erhält bei Einbinden der DLL ein Handle auf das
SharedMemory „dllmemfilemap“ und die Berechtigung zu lesen und zu schreiben.
Meldet sich ein Prozess ab, so werden dessen Ressourcen wieder freigegeben.
BOOL DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,LPVOID lpvReserved)
{
HANDLE hMapObject = NULL; // handle to file mapping
BOOL fInit;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hMapObject = CreateFileMapping(
(HANDLE) 0xFFFFFFFF, // use paging file
NULL,
// no security attributes
PAGE_READWRITE,
// read/write access
0,
// size: high 32-bits
SHMEMSIZE,
// size: low 32-bits
"dllmemfilemap");
// name of map object
if(hMapObject == NULL)
return FALSE;
fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
lpvMem = MapViewOfFile(hMapObject,
// object to map view of
FILE_MAP_WRITE, // read/write access
0,
// high offset: map from
0,
// low offset:
beginning
0);
// default: map entire file
if(lpvMem == NULL)
return FALSE;
if (fInit)
memset(lpvMem, '\0', SHMEMSIZE);
break;
case DLL_PROCESS_DETACH:
UnmapViewOfFile(lpvMem);
CloseHandle(hMapObject);
break;
default:
break;
}
return TRUE;
}
Miriam Hofmann
Bernd Frick
Seite - 29 -
Projektarbeit Sleeping Barber
Die Programmteile
Beim Öffnen der Seite mit der Petrinetz-Animation schreibt Toolbook seinen
Windows-Handle in das Shared Memory. Barber und Customer lesen es aus sobald
sie gestartet sind und haben damit einen Adressaten für ihre Messages.
Hierfür werden die folgenden Lese- und Schreibmethoden verwendet:
VOID SetSharedMem(LPTSTR lpszBuf)
{
LPTSTR lpszTmp;
// Get the address of the shared memory block.
lpszTmp = (LPTSTR) lpvMem;
// Copy the null-terminated string into shared memory.
while (*lpszBuf)
*lpszTmp++ = *lpszBuf++;
*lpszTmp = '\0';
}
VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize)
{
LPTSTR lpszTmp;
// Get the address of the shared memory block.
lpszTmp = (LPTSTR) lpvMem;
// Copy from shared memory into the caller's buffer.
while (*lpszTmp && --cchSize)
*lpszBuf++ = *lpszTmp++;
*lpszBuf = '\0';
}
Für das Starten der Prozesse benutzt die Dll die API Funktion CreateProcess():
LPCTSTR szMyApp = "Barber.exe";
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
StartupInfo.lpReserved = NULL;
StartupInfo.wShowWindow = SW_HIDE;
if(CreateProcess(szMyApp, NULL, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
NULL, NULL, &StartupInfo, &ProcessInfoBarb[iBarbCounter]))
{
iBarbCounter++;
}
Diese Funktion benötigt als Parameter im wesentlichen den Namen einer
ausführbaren Datei und Zeiger auf verschiedene Datenstrukturen. Das in StartupInfo
abgelegte SW_HIDE, um die Anzeige des Programmfensters zu unterdrücken, blieb
übrigens mit den verwendeten Borland-Programmen wirkungslos.
Miriam Hofmann
Bernd Frick
Seite - 30 -
Projektarbeit Sleeping Barber
Die Programmteile
Laut Dokumentation ist der zweite Aufrufparameter von CreateProcess() ein String
mit optionalen weiteren Kommandozeilenparametern. Der Versuch, die Prozesse
über diesen zweiten Parameter mit verschiedenen Kommandozeilen zu starten, blieb
vergebens. Erst das Folgende funktionierte:
CreateProcess(NULL, "Barber.exe woutMutex", NULL, NULL, TRUE, NORMAL_
PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInfoBarb[iBarbCounter])
Von Customer und Barber können mit CreateProcess() mehrere Prozesse angelegt
werden. Ihre Anzahl wird intern gezählt, um sie einzeln beenden zu können und ihre
Ressourcen wieder freizugeben:
bool KillBarber()
{
int iEC;
iBarbCounter--;
TerminateProcess(ProcessInfoBarb[iBarbCounter].hProcess, iEC);
CloseHandle(ProcessInfoBarb[iBarbCounter].hProcess);
CloseHandle(ProcessInfoBarb[iBarbCounter].hThread);
}
TerminateProcess() ist an dieser Stelle sehr fragwürdig, denn der Prozess selbst hat
keine Zeit, sich z.B. bei einer DLL abzumelden. Hierzu müsste er ExitProcess()
ausführen, doch das müsste er selbst tun. Hierzu müsste man ihm wohl eine
Nachricht schicken.
Die Funktion SendTBMessage() der DLL, die Barber und Customer für ihre Nachrichten
an Toolbook nutzen, wird im Abschnitt Toolbook näher betrachtet.
Funktionen einer DLL müssen im Deklarationsteil folgendermaßen deklariert sein:
extern "C" __export int SendTBMessage(UINT uiMsgNr);
Beim aufrufenden Prozess lautet die Entsprechung:
extern "C" __declspec(dllimport) int SendTBMessage(UINT MsgNr);
Bei der Kompilierung einer DLL wird eine *.lib Datei erzeugt, aus der die
zugreifenden Prozesse die Einsprungspunkte der Funktionen lesen. Diese Datei muss
bei der Kompilierung der einzelnen Prozesse jeweils mit eingebunden sein.
Miriam Hofmann
Bernd Frick
Seite - 31 -
Projektarbeit Sleeping Barber
Die Programmteile
OpenScript-Code
Kommunikation Toolbook->Dll
Die Programmiersprache von Toolbook kann dynamisch Laufzeitbibliotheken
einbinden, deren Funktionen aus OpenScript heraus nutzen und hierüber auch mit
anderen Programmen interagieren. Verschiedene DLLs werden mit Toolbook schon
mitgeliefert und bieten zum Beispiel API-Funktionen.
Die OpenScript Dokumentation befasst sich in einem eigenen Kapitel mit DLLs und
beschreibt, wie diese zu benutzen sind:
-- Bibliothek laden
LinkDLL(„MyLib.dll“)
-- Funktion deklarieren
INT Testfunktion()
-- Bibliothek entladen
end
-- Funktion benutzen
a = Testfunktion()
Leider funktioniert es so nicht.
Der richtige Befehl lautet linkDll32() und auch ist dem Funktionsnamen sowohl in
der Deklaration als auch im Aufruf ein Unterstrich voranzusetzen. Das sieht dann
beim Starten des Barbers zum Beispiel so aus:
to handle buttonClick
if Caption of button "BtnCreateBarb" = "Starte Friseur"
linkDLL32 "SleepingDll.dll"
INT _CreateBarber()
INT _KillBarber()
end
as = _CreateBarber()
enabled of button "BtnCreatecust" = true
Enabled of button "BtnStopCust" = false
Enabled of button "BtnCreateMulCust" = true
Enabled of button "BtnStopAll" = true
Caption of button "BtnCreateBarb" = "Stoppe Friseur"
else
as = _Killbarber()
enabled of button "BtnCreatecust" = false
Caption of button "BtnCreateBarb" = "Starte Friseur"
Enabled of button "BtnStopCust" = false
Enabled of button "BtnCreateMulCust" = false
Enabled of button "BtnStopAll" = false
end if
end
Toolbook kommt mit nur wenigen DLL Befehlen aus:
Es soll neben dem Speichern seines Fenster-Handles die Prozesse nur starten und
beenden können.
Miriam Hofmann
Bernd Frick
Seite - 32 -
Projektarbeit Sleeping Barber
Die Programmteile
Kommunikation Prozesse->Toolbook
Laut OpenScript –Dokumentation meldet Toolbook bei Start zwei spezielle WindowsBotschaften an, mit der es von anderen Prozessen angesprochen werden kann:
TBM_EXECUTE um eine Funktion auszuführen, und TBM_EVALUATE, um einen Parameter
auszuwerten.
Nachdem diese Botschaften in der aufrufenden Funktion registriert sind:
WORD wExecute = RegisterWindowMessage("TBM_EXECUTE");
WORD wEvaluate = RegisterWindowMessage("TBM_EVALUATE");
werden sie verwendet, wie andere Windows Botschaften auch.
SendMessage(hwndMain,wExecute,TRUE,(LONG)(LPSTR)Command); }
Lange Versuche, Toolbook mit diesen Botschaften irgendetwas mitzuteilen, blieben
leider vergebens: Toolbook stürzte durch das Senden einer TBM_EXECUTE-Botschaft
aus einer Testfunktion regelmäßig ab.
Windows Botschaften
Mit SendMessage() ist es in Windows aber auch möglich, beliebige selbstdefinierte
Botschaften zu versenden. Windows stellt hierfür einen Bereich seiner MessageNummern zur Verfügung. Diese sind ab der Botschaft WM_USER(= 0x400)
hochzuzählen. Den verwendeten Nummern wurden in der Datei Konstanten.h
sprechende Namen gegeben. Das ist in Toolbook leider nicht möglich.
Damit Toolbook auf diese Botschaften reagieren kann, ist es notwendig, einen
Handler für das Toolbook-Event Idle zu schreiben.
Hier ist das ein einfacher Dispatcher, der die empfangenen User-Messages auf die
verschiedenen OpenScript-Funktionen verteilt:
to handle idle
translateWindowMessage
on 0x700 send WacheAuf
on 0x710 send BHoleMutex
on 0x720 send BWaiting
on 0x730 send BGebeMutex
on 0x740 send ErhoeheBarber
on 0x750 send Schneide
...
..
.
Wesentlich ist hier die Verwendung von SendMessage(). SendMessage() wartet mit
seiner Rückkehr auf die Beendigung des ausgelösten Message-Handlers. So können
durch die zeitliche Dauer der Animationen die Prozesse auf ein beobachtbares Maß
verlangsamt werden, etwas, das bei den Borland-Testprogrammen durch die
Verwendung von sleep()-Funktionen erzwungen werden musste.
Miriam Hofmann
Bernd Frick
Seite - 33 -
Projektarbeit Sleeping Barber
Die Programmteile
Barber und Customer nutzen die Funktion SendTBMessage(UINT) aus der DLL, um
Toolbook ihre Botschaften mitzuteilen.
int SendTBMessage(UINT uiMsgNr)
{
if(iCustCounter < 1)
{
char lpszBuf[30];
int zahl;
LPTSTR pmem = lpszBuf;
DWORD cchSize = sizeof lpszBuf;
GetSharedMem(lpszBuf, cchSize);
zahl = atoi(lpszBuf);
hToolbook = (HWND)zahl;
}
SendMessage(hToolbook, uiMsgNr, 0, 0);
return uiMsgNr;
}
Bei Customer sieht das dann zum Beispiel so aus:
if(NULL != hBarber)
{
SendTBMessage(Warte);
if((WaitForSingleObject(hBarber, INFINITE))== WAIT_OBJECT_0)
{
CloseHandle(hBarber);
SendTBMessage(Haarschnitt);
SendTBMessage(Gehe);
Terminate();
}
}
Diese Messages sind die eigentlichen Transitionen unseres Petrinetzes. Ihre
Gestaltung beschreibt das nächste Kapitel.
Miriam Hofmann
Bernd Frick
Seite - 34 -
Projektarbeit Sleeping Barber
Die Programmteile
Animation
Jede der Botschaften von Barber und Customer löst eine Animation auf der
Toolbook-Seite aus. Die Message Handler beschreiben also im Wesentlichen nur, was
sich auf der Oberfläche der Seite bewegen soll. Folgende Funktion beschreibt
beispielsweise wie die Barber-Marke auf die freie Stelle wandert und diese aktiviert
erscheint:
to handle BGebeMutex
visible of ellipse "MarkeMu" = true
get Ellimove(ellipse "MarkeMu", arc "Arcmuvonba1", q3r, 1)
get Ellimove(ellipse "MarkeMu", arc "Arcmuvonba", q4r, 1)
get TransMoveout(ellipse "MarkeBa", button "BtnBWaiting", 2)
get shineon(ellipse "StWait", KR)
end
Die Message-Handler benutzen Grundfunktionen, die einzelne Bewegungen oder
Aktionen definieren.
Beispielhaft hier die Bewegung entlang einer elliptischen Linie, deren Parameter die
Ellipse,
die
zu
bewegende
Marke,
die
Bewegungsrichtung
und
ein
Geschwindigkeitsfaktor sind. Die Berechnung des Weges ergibt sich aus der
speziellen Ellipsengleichung:
to get Ellimove Marke, Kreis, Richtung, Fakt
get setspeed()
speed = it
speed = speed * Fakt
i = 0
a =(Width of kreis)/2
qa =((Width of kreis)/2)^2
b =(height of kreis)/2
hm = (height of Marke)/2
wm = (width of Marke)/2
lk = Left of Kreis
tk = Top of Kreis
rk = Left of Kreis + Width
bk = Top of Kreis + Height
conditions
when Richtung = Q1r
while i <= a
Move Marke to lk + a
i = i + speed
end while
when Richtung = Q1l
i = a
while i >= 0
Move Marke to lk + a
i = i - speed
end while
when Richtung = Q2L
...
..
.
of Kreis
of Kreis
+ i - wm, tk + b - sqrt(1 - i*i/qa) * b
- hm
+ i - wm, tk + b - sqrt(1 - i*i/qa) * b
- hm
Miriam Hofmann
Bernd Frick
Seite - 35 -
Projektarbeit Sleeping Barber
Die Programmteile
Ferner gibt es Funktionen, um Stellen oder Transitionen zu aktivieren und zu
deaktivieren. Für den Mehrmarkenplatz und die Anzeige der wartenden Customer
sind eigene Zähler implementiert.
Schließlich gibt es eine Rücksetzfunktion, die alle Bildschirmelemente in einen
definierten Ausgangszustand bringt.
Miriam Hofmann
Bernd Frick
Seite - 36 -
Projektarbeit Sleeping Barber
Aufgetretene Probleme
Aufgetretene Probleme
Solange
Toolbook
seine
Skripten
abarbeitet,
ist
Windows nicht bzw. nur mit
extremer
Verzögerung
ansprechbar.
Auch
unter
Windows
NT
ist
von
Prozesswechseln nichts mehr
zu bemerken. Toolbook belegt
die CPU laut Task Manager
fast zu 100%.
Das liegt vermutlich daran,
dass
Teile
der
Toolbook
Umgebung noch als 16-Bit
Programme programmiert sind
und von Windows nur exklusiv
ausgeführt werden. Dies ist
auch in der letzten Version 8.5
noch so.
Abbildung 12: Toolbook fasst zu
Solche Prozesse lassen sich „von Hand“ durch den Aufruf von PeekMessage()
unterbrechen. Das Betriebssystem arbeitet dann auch die Message-Queues anderer
anstehender Prozesse ab. Versuchsweise wurde eine Funktion implementiert, die
dies tut und bei der Abarbeitung der Skripten immer wieder aufgerufen wird:
void Peeky()
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Dadurch reagiert das System etwas schneller auf Benutzereingaben während der
Abarbeitung der Skripts, doch kommt dadurch auch die Reihenfolge der Abarbeitung
der Botschaften im animierten Petrinetz ziemlich durcheinander.
Beim Starten vieler Customer-Prozesse wird sichtbar, dass die Darstellung nicht
ganz angemessen ist: Dargestellt werden die Inhalte der Nachrichten in der
Reihenfolge ihres Einganges und nicht die Vorgänge selbst in. Das führt zeitweise zu
einem chaotischen Herumspringen der Marken. Verbesserung brächte hier eventuell
die Darstellung jedes einzelnen Customer-Prozesses, doch reicht dazu der Platz
nicht. Wünschenswert wäre, OpenScript-Kommandos von aßen direkt absetzen zu
können.
Die Dokumentation von OpenScript entspricht nicht dem Stand der 32Bit
Programmierung. linkDll32() ist darin nicht erwähnt, auch nicht ein eventuelles
Name-Mangling beim Linken der DLL.
Miriam Hofmann
Bernd Frick
Seite - 37 -
Projektarbeit Sleeping Barber
Aufgetretene Probleme
Die Verwendung der „speziellen“ Toolbook-Nachrichten TBM_EVALUATE und
TBM_EXECUTE ist im Handbuch nur unzureichend dokumentiert. Auch lange Recherche
bei den einschlägigen Newsgroups und die Benutzung von dort gefundenem
Beispielcode löste nicht das Problem eines abstürzenden Toolbook beim Empfang
solcher Botschaften.
Die Syntaxprüfung des OpenScript-Editors funktioniert nur rudimentär: Nicht einmal
falsch geschriebenen Schlüsselwörter werden beanstandet.
Die Dokumentation der Windows-API ist stellenweise falsch:
Mit dem Parameter SW_HIDE lässt sich ein Borland-Programmfenster nicht verstecken.
Will man mit CreateProcess() einem Programm Aufrufparameter übergeben, so
muss der erste Parameter des Aufrufs leer bleiben und Programmname und
Aufrufparameter im zweiten Parameter übergeben werden.
Miriam Hofmann
Bernd Frick
Seite - 38 -
Projektarbeit Sleeping Barber
Aufgetretene Probleme
Resümee
Scheiß Toolbook!
Vor allem gegen Ende der Projektarbeit, als es darum ging die verschiedenen
Elemente zu einem „Book“ zusammenzufügen, zeigte Toolbook genau das, was
schlecht programmierte Software ausmacht: Aus unerfindlichen Gründen stürzte es
ständig ab und riss dabei immer das Gesamtsystem(Windows 2000) mit in die Tiefe.
Anscheinend soll laut Asymetrix mit dem Service Pack 3 von Microsoft dieses
Problem behoben sein.
Der sogenannte Packager war minutenlang beschäftigt, und dabei nicht in der Lage
sein Fenster zu aktualisieren. Die erstellten Installationen hatten entweder keinen
Ton oder es funktionierten die Animationen nicht.
Unter 98 erstellte Installationen laufen nicht unter XP.
Dies ist mit der letzten Version (8.5) keineswegs besser. Diese besteht nach wie vor
zu Hauptteilen aus 16-Bit Modulen.
Für die nächste Version 9.0 verspricht Asymetrix eine vollständige Portierung auf 32Bit.
Miriam Hofmann
Bernd Frick
Seite - 39 -
Projektarbeit Sleeping Barber
Bedienungsanleitung
Bedienungsanleitung
Anforderungen:
Bildschirmauflösung: 1048 x 768
Farbeinstellung: 32-Bit
Sound
Windows XP
Installationshinweis:
1. Legen Sie die CD-Rom in Ihr Laufwerk und starten sie die Setup.exe mit
einem Doppelklick. Folgen Sie den Anweisungen der Installationsprogramms.
2. Die Lern-CD-Rom sollte sich nun nach erfolgreicher Installation über das
Startmenü starten lassen.
Bedienung
Die Bedienung der Software erfolgt entweder über Maus oder Tastatur. Mit der
Enter-Taste können Sie sequenziell die einzelnen Kapitel anschauen.
Mit der Maus haben Sie die Möglichkeit die Kapitel einzeln über die Bedienungsleiste
unten in der Mitte auszuwählen oder auch sequentiell über die Pfeiltasten
anzuschauen.
Schaltfläche
Beschreibung/ Kapitel
Eine Seite zurück
Intro
Beschreibung des Friseurproblems
Aufstellen eines Systemmodells
Animiertes Petrinetz
Pseudocode
Quellcode
Extro
Eine Seite weiter
Tabelle 1 Beschreibung der Buttons
Miriam Hofmann
Bernd Frick
Seite - 40 -
Projektarbeit Sleeping Barber
Abbildung 13: Bedienungsleiste
Anmerkungen zu einigen Kapiteln:
• Das Intro wird frühzeitig beendet indem Sie einfach auf eine andere Seite
gehen.
• Die Animationen im Systemmodellkapitel werden durch einen Klick auf die
Start-Buttons gestartet.
• Im Petrinetzkapitel haben Sie die Möglichkeit ein Petrinetz in Aktion zu sehen.
Zuerst muß der Friseur gestartet werden, danach können bis zu sieben
Kunden gestartet werden, diese können sie einzeln oder durch einen Klick auf
die Schaltfläche „Starte 7 Kunden „ mehrfach starten. Sie können die Seite
mit einem Klick auf „Seite zurücksetzen“ in den Anfangszustand zurücksetzen.
Sollte Ihnen die Geschwindigkeit zu langsam oder zu schnell sein, können Sie
diese Ihren Wünschen entsprechend den Radio-Buttons anpassen, dies sollten
Sie vor dem Start der einzelnen Prozesse tun. Vor dem Verlassen der Seite
sollten Sie alle Prozesse stoppen mit einem Klick auf „Stoppe Alle“.
Beendet wird die Software über einen Mausklick auf das Kreuz oben rechts in der
Caption Bar.
Miriam Hofmann
Bernd Frick
Seite - 41 -
Projektarbeit Sleeping Barber
Nachtrag
Nachtrag
Zum Abgabetermin hatten wir noch zwei ungelöste Probleme:
•
Die Animationen des animierten Petrinetzes funktionierten nur auf Rechnern,
auf denen bereits Toolbook installiert war
•
Während die Animationen liefen, waren die Rechner völlig blockiert.
Animation
Die Zeichenobjekte schienen ihre Eigenschaften „Left“, „Top“, „Width“ usw. verloren
zu haben. Nach Art der Umstände war bald klar, dass eine Unterstützungsdatei
fehlen musste.
Diese durch Probieren zu ermitteln, gaben wir bald auf.
Wir posteten an eine entsprechend Newsgroup und mailten der Supportabteilung
von Click2Learn das folgende:
Hello everybody,
as a student projekt we made a Toolbook book with ToolBook Instructor 7.1
dealing the "Sleeping Barber" problem as described in A.Tanenbaum's book.
Among pages with text there is a page with an animated Petri net,
visualizing the states of the semaphores and the processes, controlled by
a real barber process and several customer processes using Windows
messages.
We used object properties like "left", "top" and "width" to move the
tokens through the Petri net.
All works fine in author mode and also as a runtime made with the
AutoPackager, but when we tested on a computer without ToolBook Instructor
installed, the moving functions failed.
The objects, though present and e.g. changeable in their colour, seemed to
have lost their 'numerical' properties. Test functions returned NOTHING
from the "width" of a button or the "top" of it.
We wonder, what files are needed to make our ToolBook book work correct.
Thanks,
Vom Support erhielten wir die folgende Antwort:
Left, Top and Width are not standard
controllable using OpenScript...such as:
ToolBook
object
properties
left of button "foo" = 50
Normally if you want to move the object you would say:
item 1 of position of button "foo" = 50
which would simulate the same as what LEFT would have done.
When the Actions Editor support was added to ToolBook (version 7.1) a few
new functions were added (left, top and width to name a few) to support
the Actions Editor programming environment. These functions act just like
properties, which is why you can get away with saying:
Miriam Hofmann
Bernd Frick
Seite - 42 -
Projektarbeit Sleeping Barber
Nachtrag
left of <obj> = <val>
However since this LEFT function is really a supporting function of the
Actions Editor you will need to ensure that you have the TB70ACTR.SBK
system book bound to your .TBK file (use the File | Bound System Books
menu option) in order to freely utilize the Top, Left and Width functions
as you have.
It works on your Authoring machine only because the TB70ACTR.SBK
automatically loaded by the Authoring engine for Authoring purposes.
is
If this does not resolve your problem, please let me know.
Denny Dedmore
Click2Learn, Inc, Technical Support
Ein Mitglied der Newsgroup mailte:
Dear Bernd,
There are Action Editor properties like 'left', 'top', and 'width', but
they don't natively exist in OpenScript. You can create those properties
with code like:
to get top
RETURN item 2 of position of target
end
Could this be related to your problem?
Key Lawson
Und schließlich, nachdem wir ihm die Antwort der Supportabteilung weitergeleitet
hatten:
You're welcome, Bernd. Glad to help. And thank you for sending
Denny Dedmore's note. Whenever he or Tim Barham speaks, I listen.
They are terrific.
There are a bunch of those little OpenScript routines that can be
quite handy. Here are some that I use frequently:
to
to
to
to
to
to
to
to
get
get
get
get
get
get
get
get
xPos;
yPos;
width;
height;
lfEdge;
top;
rtEdge;
bottom;
to
to
to
to
to
to
to
to
set
set
set
set
set
set
set
set
xPos
yPos
width
height
lfEdge
top
rtEdge
bottom
RETURN
RETURN
RETURN
RETURN
RETURN
RETURN
RETURN
RETURN
to
to
to
to
to
to
to
to
INT
INT
INT
INT
INT
INT
INT
INT
pU;item
pU;item
pU;item
pU;item
pU;item
pU;item
pU;item
pU;item
item
item
item
item
item
item
item
item
1
2
1
2
1
2
3
4
of
of
of
of
of
of
of
of
1
2
1
2
1
2
3
4
of
of
of
of
of
of
of
of
position
position
size
size
bounds
bounds
bounds
bounds
position
position
size
size
bounds
bounds
bounds
bounds
Miriam Hofmann
of
of
of
of
of
of
of
of
of
of
of
of
of
of
of
of
target;
target;
target;
target;
target;
target;
target;
target;
target
target
target
target
target
target
target
target
=
=
=
=
=
=
=
=
pU;
pU;
pU;
pU;
pU;
pU;
pU;
pU;
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
Bernd Frick
Seite - 43 -
Projektarbeit Sleeping Barber
Nachtrag
Once these routines are in a book script or sysBook, you can code:
top of button "abc" = bottom of button "xyz"
lfEdge of mainWindow = 150
increment width of selection by 15
... anywhere you want.
or
or
etc.
They making coding life much easier.
:-)
Best,
Key
Das Systembuch TB70ACTR.SBK wurde dem Projekt hinzugefügt und in den Tests
funktioniert nun auch die Animation.
Miriam Hofmann
Bernd Frick
Seite - 44 -
Projektarbeit Sleeping Barber
Nachtrag
Windows XP
Wir fanden einen neuen Fehler:
Auf einigen Windows XP-Installationen bricht die Ausführung schon gleich zu Beginn
mit der Fehlermeldung einer allgemeinen Schutzverletzung (verursacht durch eine
16 Bit-Dll) ab. Auch hierzu einige Erkenntnisse aus der Newsgroup:
You need to upgrade to a version above 8 then *most* of the problems with
XP seem to be fixed (running as a non-admin user etc.) but there still
seem tobe a few issues...
Version 7.2 should work under XP but only when logged in as an
administrator.
"Marshall Newton" <[email protected]> wrote in message
news:[email protected]...
> Can toolbook 7.2 runtime work at all on the XP platform as I am having
>all sorts of problems.
>
>
> Thanks
>
> Marshall
>
>
Schließlich versuchten wir unser Glück noch mit den Laufzeitbibliotheken einer Trial
Version 8.5. Das Ergebnis des Versuches, das Buch zu Starten sah dann unter
Windows XP so aus:
Abbildung 14: - - -
Miriam Hofmann
Bernd Frick
Seite - 45 -
Projektarbeit Sleeping Barber
Nachtrag
Blockade
Das Problem des blockierten Rechners hat wohl auch seine Ursache in der
überholten Systemarchitektur des Entwicklungssystems:
Nach Meinung eines Windows-Experten bei IXXAT laufen die blockierenden 16-Bit
Prozesse sehr wohl als eigener Task und müssten „gesheduled“ werden wie die 32Bit Prozesse auch.
Allerdings müssen beim Datenaustausch mit 32-Bit Modulen die Daten ständig in
den 16-Bit Adressraum dieser Prozesse umgesetzt werden. Dies sei zeitaufwändig,
umständlich (Mutexe seien im Spiel) und von Microsoft kaum dokumentiert. Hier
könnten auch Prozesse beteiligt sein, die in der Liste des Task-Managers nicht
auftauchen.
Noch in diesem Jahr soll angeblich die Version 9 von Toolbook auf den Markt
kommen, die dann durchgängig 32-bittig sein soll.
Vielleicht löst ja ein Upgrade mit dieser Version unsere verbliebenen Probleme.
Miriam Hofmann
Bernd Frick
Seite - 46 -
Projektarbeit Sleeping Barber
Anhang
Anhang
AutoPackager
Das Setup-Tool des Instructors ist völlig unbrauchbar und wir verwendeten ein
anderes(http://www.jrsoftware.org/isinfo.php) .
In der ganzen Zeit hatten wir mit dem AutoPackager/InstallShield damit nur eine
einzige funktionsfähige Setupdatei hinbekommen. Unter Version 7.1 kam regelmäßig
dies,
Abbildung 15: Setupfehler
mit Version 8.5 dann auch mal das:
Abbildung 16: Setupfehler
Miriam Hofmann
Bernd Frick
Seite - 47 -
Projektarbeit Sleeping Barber
Anhang
Dateinamen hätten sich also auf 8.3 Notation zu beschränken:
Query
Title: Fatal file copy error (-1) during install when setup deployed in zip archive
Product: ToolBook
Updated: 2001-07-26
Article: Q101571559428575
Category: Instructor/Assistant
Answer
PROBLEM
------A fatal file copy error (-1) can occur while installing an autopackaged project if the setup was transferred
as a self- extracting zip archive.
Older versions of WinZip did not support long filenames. Some versions did support long filenames, but
not in the self-extracting zip archive on Windows NT 4.0. This will not happen with a newer version of
WinZip. Self-extracting files created with WinZip Self-Extractor 2.1 and later have full long file name
support.
RESOLUTION
---------A. Update to a newer version of WinZip: http://www.winzip.com
B. Do not use long filenames, use the 8.3 format (maximum 8 characters,
plus 3 character file extension).
Related articles:
- Setup has encountered a fatal file copy error (-1) - when installing...
http://kbsearch.click2learn.com/kbsearch/showart.html?article=4544
Miriam Hofmann
Bernd Frick
Seite - 48 -

Similar documents