Aufgabe 2

In dieser Aufgabe ist ein einfacher verteilter Algorithmus und dessen Verwaltung/Koordination zu implementieren. Jeder "Arbeits-"Prozess (ggT-Prozess) durchläuft den gleichen Algorithmus! Mit diesem Algorithmus kann man z.B. mit 42 ggT-Prozessen den ggT von 42 Zahlen "gleichzeitig" (nebenläufig) bestimmen. Alle benötigten Hintergrundinformationen sowie den Algorithmus finden Sie in der Datei ablauf.zip.

Lesen Sie sich die Aufgabenstellung sorgfaltig durch, damit nicht evtl. aufrgund einer Nachlässigkeit die erfolgreiche Bearbeitung gefährdet ist!

Aufgabenstellung

Das System für den verteilten Algorithmus ist so ausgelegt, dass es für eine längere Zeit installiert wird und dann für mehrere ggT-Berechnungen zur Verfügung steht, ohne dass die ggt-Prozesse oder der Koordinator neu gestartet werden müssen! Für die Implementierung werden im Wesentlichen drei Module benötigt:
  1. Der Koordinator, der den verteilten Algorithmus verwaltet. Dazu gehören das "hochfahren" des Systems, den Start einer ggT-Berechnung, die Feststellung der Terminierung einer ggT-Berechnung und das "herunterfahren" des Systems. Der Koordinator verfügt über eine GUI, in der der Algorithmus "beobachtet" werden kann und in der die benötigten steuernden Werte gesetzt werden können.
  2. Den Starter, der im Wesentlichen das Starten von Prozessen auf für den Koordinator entfernten Rechnern ermöglicht.
  3. Der ggT-Prozess, der die eigentliche Arbeit leistet, also die Berechnung des ggT.
Am Anfang wird das System hochgefahren. Dazu ist als erstes ein Namensdienst zu starten. Dann wird zunächst der Koordinator gestartet.

Das System geht nun in die Initialisierungsphase: Die Starter werden gestartet und erfragen beim Koordinator die steuernden Werte für die ggT-Prozesse. Diese werden gemäß den Vorgaben des Koordinators gestartet. Der Starter beendet sich dann selbst. Die ggT-Prozesse melden sich beim Koordinator an. Der Koordinator baut einen Ring auf und informiert die ggT-Prozesse über ihre Nachbarn. Das System ist nun bereit, ggT-Aufgaben zu lösen. Die ggT-Prozesse gehen in den Zustand "bereit".

Das System geht in die Arbeitsphase: Dazu wird zunächst das System für einen Lauf initialisiert: Der Koordinator informiert die ggT-Prozesse über ihre Werte #Mi. Er wählt 3 ggT-Prozesse per Zufall aus, die mit der Berechnung beginnen sollen. Meldet ein ggT-Prozess die Terminierung der aktuellen Berechnung, so erhält der Koordinator gleichzeitig von ihm das Endergebnis der Berechnung. Die ggT-Prozesse stehen dann für weitere Berechnungen zur Verfügung!

Erhält während einer Berechnung ein ggT-Prozess ** Sekunden lang keine Zahl y, startet er eine Terminierungsabstimmung: Dazu befragt er seinen rechten Nachbarn, ob dieser bereit ist, zu terminieren. Antwortet dieser mit Ja, sendet er dem Koordinator eine entsprechende Mitteilung über die Terminierung der aktuellen Berechnung. Wird er selbst in diesem Stadium, also als Initiator einer Abstimmung, von seinem linken Nachbarn gefragt, ob er terminieren kann, beantwortet er dies mit Ja. Wird er während seiner normalen Arbeitsphase, also wenn er nicht Initiator einer Abstimmung ist, nach seiner Bereitschaft zur Terminierung gefragt, antwortet er mit Nein, wenn seit der letzten Zusendung einer Zahl weniger als **/2 Sekunden vergangen sind. Ansonsten leitet er die Frage weiter an seinen rechten Nachbarn und leitet die zugehörige Antwort zurück an seinen linken Nachbarn.   

Das System geht in die Beendigungsphase: Der Starter ist bereits in der Initialisierungsphase beendet worden. Die ggT-Prozesse werden vom Koordinator über die Beendigung des Systems informiert. Stellt ein ggT-Prozess fest, dass er sich beenden soll (nur durch explizites close-Kommando durch den Koordinator!), hat er dies unverzüglich zu tun, unabhängig von seinem aktuellen Zustand. Die einzige dann noch zulässige Aktion ist, den Koordinator über die Beendigung zu informieren und sich beim Namensdienst wieder abzumelden. Hat der Koordinator von allen gemeldeten ggT-Prozessen die Information über deren Beendigung erhalten, beendet er sich selbst. Hat der Koordinator nach 5 Sekunden noch nicht alle Bestätigungen erhalten, beendet er sich selbst mit einer entsprechenden Fehlermeldung.

Der Ablauf ist in einer Powerpointpräsentation visualisiert (ablauf.zip); diese Präsentation wird innerhalb einer Vorlesung zusammen mit der Aufgabenstellung erklärt werden.

Funktionalität

Koordinator

  1. Der Koordinator ist als Dienst chef beim CORBA-Namensdienst registriert.
  2. Die benötigten steuernden Werte werden über die GUI eingegeben. Er hat als default-Wert bereits beliebige Werte gesetzt. Die Werte sind: ein Intervall für die Anzahl der ggT-Prozesse auf einem Rechner, ein Intervall für die Verzögerungszeit der ggT-Prozesse, ein Wert für den ** timeout und der gewünschte ggT.
  3. Durch die GUI  wird manuell per Knopfdruck der Koordinator in den Zustand "initial" gesetzt. Erst dann können sich Starter oder ggT-Prozesse bei ihm melden.
  4. Ist der Koordinator im Zustand "initial", gibt er den Startern auf Anfrage die benötigten Informationen über Anzahl der zu startenden ggT-Prozesse, deren jeweilige Verzögerungszeit und deren **-timeout. Er wählt jeweils (für jeden Starter) dazu per Zufall einen Wert aus einem in der GUI  vorgegebenem Intervall aus. 
  5. In seiner GUI werden die sich angemeldeten ggT-Prozesse angezeigt. 
  6. Wird manuell der Koordinator per Knopfdruck in den Zustand "bereit" versetzt, gibt er keinem Starter mehr Auskunft und registriert keine ggT-Prozesse mehr. Er baut nun den Ring auf, indem er per Zufall die ggT-Prozesse auswählt. Erst danach geht er in den Zustand "bereit". 
  7. Ist der Koordinator im Zustand "bereit" informiert er per Knopfdruck alle ggT-Prozesse über deren jeweilige Startwerte und startet die Berechnung. Für die Startwerte liest er aus der GUI einen aktuellen gewünschten ggT aus und multipliziert ihn wie folgt:
         gewünschter_ggT * 
    Zufallszahl_1_bis_100 * Zufallszahl_1_bis_100.
  8. Er wählt dann per Zufall drei Prozesse aus, denen er zum Starten der Berechnung eine Zahl sendet, die sich wie folgt berechnet:
       gewünschter_ggT * Zufallszahl_100_bis_10000
    .
  9. In seiner GUI zeigt der Koordinator die Nachrichten der ggT-Prozesse an, insbesondere zeigt er an, welcher Prozess ihm die Terminierung der aktuellen Berechnung gemeldet hat und was das Endergebnis ist. 
  10. Per Knopfdruck kann der Koordinator dann in den Zustand "beenden" versetzt werden oder eine neue ggt-Berechnung starten.
  11. Ist der Koordinator im Zustand "beenden" informiert er die ggT-Prozesse über die Beendigung und wartet maximal 5 Sekunden auf deren Bestätigung. 
  12. Haben alle ggT-Prozesse die Beendigung bestätigt, beendet er sich selbst mit entsprechender Meldung. Hat er nach 5 Sekunden nicht alle Bestätigungen erhalten, beendet er sich mit entsprechender Meldung.
    In seiner GUI gibt er die bei der Bestätigung von den ggT-Prozessen mitgesendeten Informationen aus.
  13. Koordinator ist in Java zu implementieren und muss auf jedem Rechner im Labor startbar sein! Erzeugen Sie dazu eine ausführbare Datei!
     

Starter

  1. Der Starter erfragt beim Koordinator die steuernden Werte, bis er diese vom Koordinator erhält oder er zehn Versuche durchgeführt hat.
  2. Der Starter startet die ggT-Prozesse mit den zugehörigen Werten: der Verzögerungszeit, die Terminierungszeit und der Startnummer dieses Prozesses (also der wievielte gestartete ggT-Prozess er ist) und die Nummer seines Starters. 
  3. Sind alle ggT-Prozesse gestartet beendet sich der Starter dann selbst.
  4. Beim starten des Starters wird ihm seine Nummer mitgegeben sowie die TeamID (die zu erfragen ist).
  5. Der Starter ist in Java zu implementieren und muss auf jedem Rechner im Labor startbar sein! Sie können hier auch meine Vorgabe verwenden: starter.jar (Aufruf mit java -jar starter.jar <starterNR> <rechnername> <port> <pfadname des programms> <programmname>). 

ggT-Prozess

  1. Der ggT-Prozess ist mit dem Namen slave????? beim CORBA-Namensdienst registriert. Dabei ist ????? eine Zahl, die sich wie folgt zusammensetzt:
       <PraktikumsgruppenID><TeamID><Nummer des ggT-Prozess><Nummer des Starters>
    ,
    also z.B. ist in der Praktikumsgruppe 3 (einstellige Zahl) von dem Team 03 (zweistellige Zahl) ein dritter ggT-Prozess  (einstellige Zahl) von ihrem ersten Starter (einstellige Zahl) gestartet worden, so erhält dieser ggT-Prozess den Namen slave30331
    In der Kommunikation zwischen ggT-Prozess und Koordinator oder anderen ggT-Prozessen wird stets auf den Zusatz slave verzichtet, also nur die Nummer übertragen!
  2. Der ggT-Prozess meldet sich beim Koordinator mit seinem Namen an, bis dieser die Anmeldung akzeptiert oder er es zehn mal probiert hat.
  3. Der ggT-Prozess erwartet nun steuernde Werte vom Koordinator (Nachbarn und seine Zahl Mi). Er hat bereits default-Werte zu Anfang gesetzt, die beliebig/frei gewählt wurden.
  4. Der ggT-Prozess reagiert nun auf die jeweiligen Nachrichten. Wenn er z.B. eine Zahl erhält führt er den ggt-Algorithmus aus. 
  5. Ändert sich seine Zahl dadurch (also hat er echt etwas berechnet), informiert er zusätzlich den Koordinator darüber, indem er diesem seinen Namen, seine neue Zahl und die aktuelle Systemzeit überträgt.
  6. Ändert sich seine Zahl dadurch nicht und war es das erste mal, dass er eine Zahl erhalten hat, gibt er eine Fehlermeldung aus und sendet seinem rechten Nachbarn seine Zahl #Mi. Diese Aktion wird ausschliesslich beim ersten Aufruf einer neuen Berechnung durchgeführt. Ansonsten macht der ggt-Prozess in diesem Fall gar nichts!
  7. Für eine Berechnung braucht er jedoch eine gewisse Zeit (die Verzögerungszeit), die ihm vom Starter bei der Initialisierung mitgegeben wurde. Dies simuliert eine größere, Zeit intensivere Aufgabe. Der ggT-Prozess sollte in dieser Zeit einfach nichts tun (usleep).
  8. Der ggT-Prozess beobachtet die Zeit seit dem letzten Empfang einer Zahl. Hat diese ** Sekunden überschritten, startet er eine Terminierungsanfrage. Es wird nur genau eine Terminierungsanfrage gestartet; eine weitere kann erst gestartet werden, wenn die erste (positiv oder negativ) beendet wurde! 
  9. Ist Terminierungsanfrage erfolgreich durchgeführt, sendet er dem Koordinator eine Mitteilung über die Terminierung der aktuellen Berechnung, die seinen Namen, den errechneten ggT und seine aktuelle Systemzeit beinhaltet. Die Abstimmung arbeitet wie folgt: 
    1. Ein ggT-Prozess erhält die Anfrage nach der Terminierung und er ist nicht der Initiator: ist seit dem letzten Empfang einer Zahl mehr als **/2 (** halbe) Sekunden vergangen, dann leitet er die Anfrage an seinen rechten Nachbarn weiter (implizites Zustimmen) und gibt dessen Antwort zurück an seinen linken Nachbarn. Sonst antwortet er seinem linken Nachbarn direkt mit Nein (explizites ablehnen). 
    2. Erhält ein initiierende Prozess von seinem linken Nachbarn die Anfrage nach der Terminierung, antwortet er diesem direkt mit Ja ohne weitere Aktionen durchzuführen.
    3. Ein initiierender ggt-Prozess erhält ein Ja auf seine Terminierungsanfrage: Der ggt-Prozess meldet dem Koordinator die Terminierung und wartet anschliessend auf eine neue Berechnungsaufgabe oder das explizite close-Kommando zum Beenden.
  10. Ein ggt-Prozess zählt intern die Anzahl aller Terminierungsanfragen (inklusive seiner initiierten Anfragen) sowie die Anzahl aller Antworten. In einer dritten Variablen werden Terminierungsanfragen gezählt (+1) und Antworten abgezogen (-1) .
  11. Der ggT-Prozess ist in C++ zu implementieren und muss auf jedem Rechner im Labor startbar sein! Erzeugen Sie dazu eine ausführbare Datei!

GUI

  1. Der Koordinator hat eine GUI über die die benötigten steuernden Werte gesetzt werden.
    1. In der GUI sind die angemeldeten ggT-Prozesse zumindest so lange anzuzeigen, bis der Koordinator in den Zustand "bereit" übergeht.
    2. Die GUI zeigt während einer Berechnung die Nachrichten der ggT-Prozesse an. 
    3. Alle ausgegebenen Daten werden in der Datei chef.log mit protokolliert.
  2. Der Starter und die ggT-Prozesse protokollieren ihre Ausgaben in der Datei slave?????.log bzw. starter???.log. Dabei ist die Identität des ggT-Prozesses bzw. die ersten drei Ziffern der ggT-Prozesse eines Starters. 
    1. Zu protokollieren sind alle Informationen über den aktuellen internen Zustand, d.h. der Starter protokolliert die erhaltenen steuernden Werte und die Aufrufe der ggT-Prozesse. 
    2. Die ggT-Prozesse protokollieren ihre Zustandsänderungen und alle Nachrichten, die sie erhalten oder versenden.
  3. Alle Prozesse protokollieren in den *.log Dateien alle ihre Fehlermeldungen.

Fehlerbehandlung

  1. Wann immer die Besorgung einer IOR schief geht, ist eine Fehlermeldung auszugeben und auch in der zugehörigen Protokolldatei zu vermerken. Handelt es sich um einen ggT-Prozess, streicht der Koordinator ihn, sofern der Ring noch nicht aufgebaut wurde, aus seiner Liste; ein ggT-Prozess, der die IOR einer seiner Nachbarn oder des Koordinators nicht erhält, beendet sich mit einer entsprechenden Fehlermeldung.
  2. Tritt während dem Lauf ein Fehler in der Kommunikation auf, erzeugt der rufende Prozess eine entsprechende Fehlermeldung, die auch in der zugehörigen Protokolldatei zu vermerken ist. Er beendet sich dann selbst. Handelt es sich hier um den Koordinator, beendet er alle ggT-Prozesse.

IDL

Die folgende IDL beschreibt die Schnittstelle des Koordinators.

module chef{
    interface koordinator{
        /* initial */
        long getsteeringval(out long pnum, out long wtime,out long term);
        long hello(in long pid);
        /* bereit */
        oneway void briefmi(in long pid, in long pm, in long ptime);
        oneway void briefqu(in long pid, in long ptime);
        oneway void briefre(in long pid, in long ptime);
        oneway void terminated(in long pid, in long ggt, in long ptime, in long rcount, in long qcount);
        /* beenden */
        oneway void closed(in long pid, in long pm, in long ptime);
    };
};

getsteeringval: Fragt beim Koordinator die steuernden Werte ab; diese sind die Anzahl der ggT-Prozesse (pnum), die Verzögerungszeit für die ggT-Prozesse (wtime) in Sekunden und den **-timeout in Sekunden (term). Als Rückgabewert erhält er einen Fehlercode, mit 1 = OK und 0 = error.

hello: Ein ggT-Prozess sendet dem Koordinator seinen Namen, wobei auf den Zusatz slave verzichtet wird. Als Rückgabewert erhält er einen Fehlercode, mit 1 = OK und 0 = error.

briefmi: Ein ggT-Prozess sendet dem Koordinator seinen Namen (pid), seine aktuelle Zahl Mi (pm) und seine aktuelle Systemzeit (ptime), die durch eine 6-stellige Zahl repräsentiert wird (hhmmss).

briefqu: Ein ggT-Prozess sendet dem Koordinator seinen Namen (pid) und seine aktuelle Systemzeit (ptime), die durch eine 6-stellige Zahl repräsentiert wird (hhmmss), wenn er als Initiator eine Antwort auf seine Anfrage erhält. Die Methode ist per synchronized als kritischer Abschnitt zu schützen.

briefre: Ein ggT-Prozess sendet dem Koordinator seinen Namen (pid) und seine aktuelle Systemzeit (ptime), die durch eine 6-stellige Zahl repräsentiert wird (hhmmss), wenn er eine Terminierungsanfrage initiiert. Die Methode ist per synchronized als kritischer Abschnitt zu schützen.

terminated: Ein ggT-Prozess, der die Terminierung einer Berechnung festgestellt hat, sendet dem Koordinator seinen Namen (pid), und den berechneten ggT (ggt) sowie seine aktuelle Systemzeit (ptime), die durch eine 6-stellige Zahl repräsentiert wird (hhmmss). Zudem sendet er seine query- (qcount) und response-Zähler (rcount).

closed: Ein ggT-Prozess sendet dem Koordinator zur Bestätigung, dass er sich beendet, seinen Namen (pid), und den berechneten ggT (ggt) sowie seine aktuelle Systemzeit (ptime), die durch eine 6-stellige Zahl repräsentiert wird (hhmmss).

Die folgende IDL beschreibt die Schnittstelle der ggT-Prozesse.

module ggt{
    interface unit{
        /* initial */
        long setneighbors(in long pidleft, in long pidright);
        oneway void setpm(in long pm);
        /* rechnen */
        oneway void sendy(in long y);
        oneway void query(in long pid);
        oneway void response(in long pid,in long y);
        /* beenden */
        oneway void close( );
    };
};

setneighbors: Der Koordinator teilt einem ggT-Prozess seinen linken (pidleft) und rechten (pidright) Nachbarn des logischen Ringes mit, indem er die entsprechenden Nummeren der Nachbarn (ohne Zusatz slave) mitteilt. Als Rückgabewert erhält er einen Fehlercode, mit 1 = OK und 0 = error.

setpm: Der Koordinator teilt einem ggT-Prozess seine interne Zahl Mi (pm) mit.

sendy: Ein ggT-Prozess (oder beim Start der Koordinator) sendet die Zahl Mi (y) an einen (benachbarten) ggT-Prozess.

query: Ein ggT-Prozess hat den **-timeout festgestellt und befragt seinen rechten Nachbarn, ob er mit der Terminierung einverstanden ist. Der Prozessnamen (pid) ist der Name des Initiators der Abstimmung und wird durchgereicht oder als Initiator gesetzt. Diese Methode ist nicht als kritischer Abschnitt zu schützen!

response: Ein ggT-Prozess beantwortet die Frage nach der Terminierung (y =) mit 0 für Nein und 1 für Ja. Der Prozessnamen (pid) ist der Name des Initiators der Abstimmung und wird durchgereicht oder als Initiator gesetzt. Diese Methode ist nicht als kritischer Abschnitt zu schützen!

close: Der Koordinator (oder im Fehlerfall ein ggT-Prozess) sendet einem ggT-Prozess die Aufforderung, sich zu beenden.

Tipp

Verwenden Sie die Dateien aus Aufgabe 1 und passen Sie diese an, insbesondere die Dateien von C++. Beginnen Sie mit den Arbeiten nicht erst im Praktikum! Damit Sie die Betreuung z.B. zur Klärung von Fragen nutzen können und damit Sie die Befragung am Anfang des Praktikums erfolgreich absolvieren können, ist die Aufgabe gut vorzubereiten! Zum Testen können Sie eine beispielhafte Lösung verwenden, die in Raum 765 lauffähig ist: exeFile.zip. Lesen Sie zum Starten die README Dateien.

Strukturieren Sie Ihr Programm gut: sofern Sie den Rechnernamen und Port fest kodieren, machen Sie es zentral an einer Stelle! Besorgen Sie sich zentral an einer Stelle die Stellvertreter der entfernten Objekte (narrow) und nicht etwa bei jedem Zugriff. Trennen Sie gut zwischen den Aktivitäten für CORBA und den eigentlichen inhaltlichen Aufgaben.

Ein Hinweis zu dem IDL-Datentyp string: Dieser wird als char* in C++ übersetzt und stets mit NUL beendet. Hinweise zur Programmierung finden Sie hier (*.pdf, OMG Quelle, Abschnitt 1.7 Mapping for String Types). Dies zeigt, dass Zeichenketten stets ein kleines Problem mit sich bringen und daher mit Vorsicht behandelt werden sollten.

Da für die Lösung auch Threads nützlich sein können, sollten Sie ggf. zur Wiederholung die Folien von Kollegen Hübner zu dem Thema durcharbeiten (*.zip, 69 kB) und ggf. einige Beispiele (*.zip, 30 kB) dazu erstellen. Hier ein Beispiel für C++:

Slave *ggT;

void *thread_routine (void *aggT) {
    Slave *myggT = (Slave *) aggT;
    while (1) {
            sleep(1);
                myggT->checkTimeout();
    }
    return NULL;
}
...
int main (int argc, char *argv[]) {
...
   pthread_t timeoutcheck;
    int status = pthread_create ( &timeoutcheck, NULL, thread_routine, (void*) ggT);
...
}

Zum externen Aufruf eines C++-Programms aus Java heraus: Suchen Sie im WWW nach einer Lösung, z.B. das Native Interface von Java (JNI). Eine einfache Möglichkeit wäre:
 Runtime rt = Runtime.getRuntime(); 
Prozess p = null;
int status = 0;

try
{
p = rt.exec("./a.out"); // starte kompiliertes C-/C++-Programm ./ ist der Pfad für Linux cmd /c für Windows
}
catch (IOException exc)
{
System.err.println("Problem beim Ausf\u00FChren von \"a.out\"!");
System.err.println(exc);
exc.printStackTrace();
System.exit(1);
}
Das Praktikum wird auch von Kollegen Hartmut Schulz mit betreut, der auf seinen WWW-Seiten weitere Informationen zu den Aufgaben hat! Halten Sie das System einfach. Wenn die Kernfunktionalität erstellt wurde, kann das System immer noch beliebig erweitert/verbessert werden. Weitere Informationen, Beispiele, etc., finden Sie im WWW.

Abnahme

Da die Aufgaben des VSP sehr frühzeitig im WWW zur Verfügung stehen, wird die Abnahme stark auf eine vorbereitende Arbeit aufgebaut. Erfahrungen aus den letzten Praktika haben gezeigt, dass sonst erhebliche Nacharbeiten stattfinden und dadurch eine wesentliche zeitliche Verzögerung bewirkt wird, die zu einem erhöhten Arbeitsaufkommen gerade vor den Prüfungswochen führt.
 
Bis Montag Abend vor Ihrem Praktikumstermin ist ein erster Entwurf für Teil 2 der Aufgabe als *.pdf Dokument mir per E-Mail über den Verteiler abgabe_aivsp@ zuzusenden. Ggf. können offene Fragen mit gesendet werden. Geben Sie bitte auch an, wer zu Ihrem Team dazu gehört (inklusive E-Mail Adresse!). Der Entwurf darf keinen Code beinhalten, da er nicht in dieser Detailebene "angesiedelt ist". Der Entwurf muss bzgl. des aktuellen Standes der Entwicklung die Klassendiagramme und die Sequenzdiagramme bzgl. der Kommunikation zwischen den Prozessen beinhalten (z.B. kann für Sequenzdiagramme folgendes Tool gut verwendet werden: Quick Sequence Diagram Editor.) sowie eine Erklärung der Architektur. Der Entwurf ist für die PVL wichtig: sollten die Abgabefrist und/oder die erforderlichen Inhalte nicht eingehalten bzw. erbracht worden sein, gilt die Aufgabe als nicht erfolgreich bearbeitet!
 
Zwischen 08:15 und 09:00 findet am Tag des Praktikums eine Befragung von Teams statt. Die Befragung muss erfolgreich absolviert werden, um weiter am Praktikum teilnehmen zu können. Ist die Befragung nicht erfolgreich, gilt die Aufgabe als nicht erfolgreich bearbeitet. Als erfolgreich wird die Befragung bewertet, wenn Ihre Kenntnisse eine erfolgreiche Teilnahme an dem Praktikumstermin in Aussicht stellen. 

Zwischen 10:45 und 10:55 haben Sie selbst einen Eingangstest durchzuführen, der darüber entscheidet, ob Sie an einer Vorführung teilnehmen können. Achtung: ein Nachholtermin für das gesamte Praktikum bzw. die Vorführung ist nicht vorgesehen!
Zwischen 10:55 und 11:25 findet eine gemeinsame Vorführung statt. Bei der Vorführung wird per Zufall ausgewählt, welcher Koordinator eines Teams zum Einsatz kommt. Alle Teams (auch das Team, das den Koordinator gestartet hat) haben ihre ggt-Prozesse zu starten.

Zwischen 11:25 und 11:30 findet ggf. eine Befragung von Teams zu ihrem Code statt. Diese muss erfolgreich absolviert werden, um weiter am Praktikum teilnehmen zu können. Ist die Befragung nicht erfolgreich, gilt die Aufgabe als nicht erfolgreich bearbeitet.

AbgabeUnmittelbar am Ende des Praktikums ist von allen Teams der Code abzugeben. Zu dem Code gehören die Sourcedateien und die *.log Dateien, die während der Vorführung erzeugt wurden sowie die *.log Dateien, die beim Eingangstest erzeugt wurden! Bitte beachten Sie: es muss klar sein, welche *.log Dateien zu welcher Vorführung bzw. zu welchem Test gehören!

Im Code ist zu kommentieren, wo die oben aufgeführten Punkte umgesetzt wurden! Zudem ist zu beschreiben, wie das Programm gestartet wird. Die Abgabe gehört zu den PVL-Bedingungen und ist einzuhalten, terminlich wie auch inhaltlich!

Wird eine Aufgabe nicht erfolgreich bearbeitet gilt die PVL als nicht bestanden. Damit eine Aufgabe als erfolgreich gewertet wird, müssen beide Befragungen, der Eingangstest sowie die Vorführung als erfolgreich gewertet werden. Zudem muss der Entwurf wie auch die Abgabe korrekt durchgeführt worden sein. Alle gesetzten Termine sind einzuhalten. Dies ist notwendig, da aufgrund der Größe der Praktikumsgruppen sonst erhebliche zeitliche Verzögerungen entstehen würden. 



gratis Counter by GOWEB
Gratis Counter by GOWEB