2017-12-15 6 views
-1

Zusammenfassung Aufruf

ich an einem Projekt arbeite und fand dieses Problem:Java RMI gefriert, während eine Funktion auf einem Stummel

Wir haben ein Problem in unserem Code gefunden, die wir nicht lösen können. Zuerst geben wir einige allgemeine Informationen über das Eclipse-Projekt und wie es ausgeführt werden kann, dann geben wir einige Details über den Code und schließlich beschreiben wir das Problem.

Das Projekt

Wir haben ein Java Maven-Projekt in Eclipse gebaut. Es enthält zwei Quellordner: src/main/java und src/test/java. Der Hauptordner enthält eine Implementierung des Algorithmus von Gallager, Humblet und Spira. In diesem Moment haben wir einen Test SimpleTest, um zu sehen, ob grundlegende Funktionalitäten des Algorithmus wie erwartet funktionieren. Der Code kann wie folgt ausgeführt werden:

  1. Entpacken Sie die angehängte Datei DA-Lab3.zip.
  2. Öffnen Sie ein Befehls/Terminal-Fenster im Ordner DA-Lab3/target/classes.
  3. Starten Sie die Java RMI-Registrierung in diesem Verzeichnis ("rmiregistry &" in Linux, "Start rmiregistry" in Windows).
  4. Wechseln Sie zum Ordner DA-Lab3 im Befehls-/Terminalfenster.
  5. Ausführen: "mvn clean install -f.". (Wenn das nicht funktioniert, weil Maven einen Ordner nicht säubern kann, versuche denselben Befehl ohne "clean".) Nun sollten die Testdateien von Java/Maven ausgeführt werden.

Der Code

Der Code in mehrere Teile aufgeteilt wird. Die wichtigsten Teile sind Node, Process und RMINetwork. Knoten enthält den eigentlichen Algorithmus, Process erweitert Node um praktische Funktionen wie das Erstellen von Kanten, das Implementieren der Sendemethode und das Entfernen von Kanten. RMINetwork behandelt RMI-bezogene Funktionen wie das Registrieren eines Prozesses in der Registrierung, das Aufheben der Registrierung eines Prozesses und das Nachschlagen anderer Prozesse im RMINetwork.

Der Knoten befindet sich im GHS.graph-Paket. Das Paket enthält außerdem Edge, NodeState und EdgeState. Nachrichten werden von der Empfangsfunktion (Zeile 221) verarbeitet. Jeder Nachrichtentyp implementiert das Interface GHS.messages.IMessage mit dem Funktionsprozess. Die Empfangsfunktion in Node ruft diese Prozessfunktion in jeder Nachricht auf. Aus diesen Prozessfunktionen in den Nachrichten werden bestimmte Funktionen in Node aufgerufen. Diese Funktionen in Node verarbeiten Nachrichten gemäß dem Algorithmus.

Prozess ist in der Packung GHS platziert. Es erweitert Node um eine ID-Variable und die Funktionen send, connect, disconnect, id(), run und stop. Die Sendefunktion bestimmt die ID des Empfängers und gibt dem RMINetwork die Aufgabe, eine Nachricht an den Empfänger zu senden. Die Process-Klasse implementiert auch die IProcess-Schnittstelle. Diese Schnittstelle wird von RMI-Clients verwendet.

RMINetwork wird in die Paketkommunikation eingefügt. Diese Klasse enthält Funktionen zum Registrieren, Abmelden, Suchen und Senden.

Das Problem

In Simple Test1 drei Prozesse und eine Kante erzeugt werden. Prozess 0 stellt eine Verbindung zu Prozess 2 her. Dann wird Prozess 0 aktiviert und eine Verbindungsnachricht an Prozess 2 gesendet.Prozess 2 wacht auf und sendet eine Verbindungsnachricht zurück an Prozess 0. Dann Prozess 0 sendet eine Initiate-Nachricht an Prozess 2. Aber hier scheint Java Freez ohne Fehler zu werfen.

ins Detail zu gehen: Java scheint zu stecken: ((IProcess) this.lookup(id)).receive(edge, message); RMINetwork r: 52.

Um zu sehen, was das eigentliche Problem ist, dass wir einig Test-Code für die Funktion hinzugefügt. In Zeile 49 wir hinzugefügt: IProcess p = (IProcess) this.lookup(id); Und Zeile 50: String s = p.id(); Row 51: System.out.println("networking"); Mit diesem Testcode aktiviert Java stucks in Zeile 50.

Wenn Reihe 50 deaktiviert ist, Zeile 51 ausgeführt und Java stucks in Zeile 52.

Die Funktion p.id() ist in Process implementiert. Die erste Anweisung gibt eine Zeichenfolge an die Befehlszeile aus. In dem Moment, in dem Java festsitzt, wird diese Druckanweisung nicht ausgeführt.

Wenn wir Zeile 49 durch 49 ersetzen, haben wir hinzugefügt: IProcess p = (IProcess) this.lookup(edge.neighbour(id)); (der Absender sucht jetzt tatsächlich seine eigene ID), dann passiert das Problem beim Senden der zweiten anstelle der dritten Nachricht.

So scheint es, dass Java RMI bei einem Aufruf auf einem Stub friert. Aber es funktioniert immer für die erste Nachricht und, abhängig von Zeile 49, für die zweite Nachricht. Da kein Fehler auftritt, haben wir keine Ahnung, warum RMI an dieser Stelle einfriert.

@Override 
public void send(String id, Edge edge, IMessage message) throws Exception { 
    System.out.println("testing"); 
    IProcess p = (IProcess) this.lookup(id); 
    String s = p.id(); 
    //System.out.println(((IProcess) this.lookup(id)).id()); 
    System.out.println("networking"); 
    ((IProcess) this.lookup(id)).receive(edge, message); 
    System.out.println("id found"); 
} 

Wir hoffen, dass Sie uns helfen können.

können Sie den gesamten Code sehen: https://github.com/mboom/DA-Lab3

Antwort

0

Es stellte sich heraus, dass die Prozesse in einem einzigen Thread aufeinander warteten. Alte initiierte Methoden, die Nachrichten an andere Prozesse senden, waren im Moment noch nicht fertig, ein anderer Prozess, der über einen Stub eine Methode genannt wurde. Diese Methoden werden nicht gestartet, solange die alten Methoden ausgeführt werden. Da die alten Methoden auf eine Antwort warten (die erst dann kommt, wenn diese alten Methoden beendet sind), befand sich das System in einem Deadlock. Wir haben das Problem gelöst, indem wir die Empfangsmethode von Knoten in einem neuen Thread ausgeführt haben.

0

Die Remote-Methode nicht aufgerufen wird, zurückkehrt.

+1

In diesem Fall friert Java auf 'String s = p.id();' und es sollte die ID des Prozesses zurückgeben (siehe https://github.com/mboom/DA-Lab3/blob/master/src /main/java/GHS/Process.java Zeile 66). Daher bin ich mir nicht sicher, was du meinst. Denken Sie, dass ein unerwartetes Verhalten auftritt, das dazu führt, dass die Funktion id() nicht zurückkehrt? –

+0

Das ist nicht, wo es heißt, Sie frieren in Ihrer Frage, aber was immer Sie anrufen, es kommt nicht zurück, wie ich bereits sagte. NB: Ich habe endlich herausgefunden, dass wenn Sie "Zeile" sagen, Sie "Linie" meinen. Die Standardterminologie nicht missbrauchen. – EJP

+0

Hmm, okay. Ich bedauere die Terminologie :(. Danke für Ihre Antwort. –