2017-02-15 1 views
0

Die Simulation läuft aber in der Konsole habe ich diesen Hinweis.omnet ++: Selbstnachricht als entsorgtes Objekt

undisposed Objekt: (omnetpp :: cMessage) Mysimulation.Switch4.eth [2] .queue.scheduler.IntervalTimemsg - prüfen Modul destructor undisposed Objekt: (omnetpp :: cMessage) Mysimulation.Switch5. eth [1] .queue.scheduler.IntervalTimemsg - prüfen Modul destructor

Eigentlich ist es ein Modul, das ich habe zwei Zeitnachricht über und über durch die Simulation erstellt werden. Ich habe online gelesen und festgestellt, dass dieser Fehler mit dem Erstellen von Objekten zusammenhängt, die zum Zeitpunkt des Löschens nicht gelöscht wurden.

void PriorityScheduler::initialize() { 
gateCycleTimemsg = new cMessage("gateCycleTimemsg"); 
scheduleAt(baseTime , gateCycleTimemsg); 
// baseTime = 2s 
} 

void PriorityScheduler::handleMessage(cMessage *msg) { 
    if (msg == gateCycleTimemsg) { 

     if (currentList == (lastIntervalTime)) { 
     delete msg; 
     gateCycleTimemsg = new cMessage("gateCycleTimemsg");  
     scheduleAt(simTime() + gateCycleTime , gateCycleTimemsg); 
     ... 
     IntervalTimemsg = new cMessage("IntervalTimemsg"); 
     scheduleAt(simTime() + Interval , IntervalTimemsg); 
     } 

     else if (currentList == (firstIntervalTime)) { 
     gateCycleTimemsg = msg; // same message reused 
     scheduleAt(simTime() + gateCycleTime , gateCycleTimemsg); 
     //gateCycleTime = 10 seconds 
     ... 
     IntervalTimemsg = new cMessage("IntervalTimemsg"); 
     scheduleAt(simTime() + Interval , IntervalTimemsg); 
     // Interval = 1s 
     } 
    } 

    else if (msg == IntervalTimemsg) { 
     if (currentList == (lastIntervalTime));  
     else{ 
     IntervalTimemsg = msg;     
     scheduleAt(simTime() + Interval , IntervalTimemsg); 
     } 
} 

Plugin Pfad: /home/amr/omnetpp-5.0/samples/etc/plugins;./plugins nach dem Werfen einer Instanz 'omnetpp :: cRuntimeError' was() aufgerufen terminate: Object pk-56-145 ist derzeit in (omnetpp :: cEventHeap) simulation.scheduled-events, es kann nicht gelöscht werden. Wenn dieser Fehler innerhalb von omnetpp :: cEventHeap auftritt, muss er geändert werden, um drop() aufzurufen, bevor das Objekt gelöscht werden kann. Wenn dies Fehler innerhalb omnetpp auftritt :: cEventHeap Destruktor und pk-56-145 ist ein Klassenmitglied, omnetpp :: cEventHeap muss Drop() aufzurufen, in dem destructor

ich einen Konstruktor erstellt sowie Destruktor. Ich habe auch die Funktion finish() erstellt, nachdem ich online nach Lösungen gelesen habe. Trotzdem hat es das nicht gelöst.

Ich entfernte auch jede Nachricht erhalten und erstellt eine neue beim Senden, aber es hat nichts geändert.

bearbeiten: Ich bearbeitet die Codierung mit löschen msg; Ich fügte hinzu, und gab ein Beispiel von Timings und hinzugefügt, um das unten Teil,

BaseTime ‚BT‘, gateCycleTime ‚CT‘, Intervall ‚IT‘

----> BT    
     <---- IT1 ----> <----- IT2 ----> .........<-------- ITx -------->  
     <------------------------------ CT -----------------------------> 

habe ich die gleiche Nachricht für BT und CT, während ein anderer Nachricht für ITs, da ich das Timing der letzten IT 'ITx' nicht kenne.

Antwort

3

Sie erstellen neue Timer (Nachrichten), löschen jedoch nie die alten. Das Löschen der Nachricht während der Verarbeitung funktioniert nicht (daher die Fehlermeldung).

Mein Vorschlag (ohne etwas Bestimmtes über Ihre Simulation zu wissen):

  1. die Timer-Nachricht in Ihrer Initialisierung Funktion erstellen, sobald (zum Beispiel)
  2. in if (msg == gateCycleTimemsg) -> prüfen, ob der Nachrichtenzeitgeber ist bereits geplant
  3. , wenn die Timer-Nachricht bereits geplant ist, den Timer beenden und wieder neu planen, aber nicht ein neues
  4. zu erstellen, wenn der Timer nicht geplant ist, Zeitplan (create) es (zum ersten Mal scheinbar)
  5. für else if (msg == IntervalTimemsg) -> dies wird aufgerufen, wenn der Timer experimentiert (die Selbstnachricht wurde übermittelt), daher nur den Timer neu planen, aber keine neue Nachricht erstellen.

Sie können mehr über Selbst Nachrichten lesen (oft für Timer verwendet wird) in der OMNeT ++ Handbuch: https://omnetpp.org/doc/omnetpp/manual/#sec:simple-modules:self-messages

+0

Nun, ich lese das Dokument und ich kann es immer noch nicht lösen. Das Problem, dass ich zwei Timings nicht eins parallel habe. Mit 'delete msg;' lösche ich beide, wenn ich mich nicht irre. 139 Fehlercode –

+1

verursachen Zuerst ist das Löschen einer Nachricht innerhalb von handleMessage, ohne die Funktion selbst zu unterbrechen, gefährlich, da andere 'if (msg == ...)' Prüfungen fehlschlagen, da Sie die Nachricht gelöscht haben. Zweitens sind zwei Timings nur zwei Timer, Sie löschen einen Timer nicht, Sie löschen ihn nur, wenn sich der Zustand des Timers ändert, bevor er beendet ist (es hat keine Zeit mehr). Die Verwendung der gleichen Nachricht für zwei Timer könnte Sie mehr verwirren, als es hilft. Verwenden Sie für jeden Timer eine separate Timer-Nachricht, erstellen Sie sie bei Bedarf und brechen Sie sie bei Bedarf ab oder verschieben Sie sie neu. Löschen ist möglicherweise nur im Destruktor erforderlich. –

1

Im Allgemeinen Timer sollte nicht in der handle() Funktion erstellt werden, um die Schöpfung und Zerstörung zu vermeiden Objekte in jedem Aufruf. Daher sollte die Initialisierungsfunktion die Nachrichten

void PriorityScheduler::initialize() { 
    gateCycleTimemsg = new cMessage("gateCycleTimemsg"); 
    IntervalTimemsg = new cMessage("IntervalTimemsg"); 
    scheduleAt(baseTime , gateCycleTimemsg); 
} 

und die Zielfunktion erstellen oder die destructor sollten sie reinigen.

void PriorityScheduler::finish() { 
    cancelAndDelete(gateCycleTimemsg); 
    cancelAndDelete(IntervalTimemsg); 
} 
+1

Vielen, vielen Dank, aber ich erwähnte bereits, ich schuf Finish sowie Destruktor und Konstruktor. Der Destruktor und der Konstruktor, die die Nachrichten auf nullptr setzen, geben den Fehler 137 oder 139 aber 'finish()' nicht, es sei denn, ich habe bereits cancelEvent() oder CancelanDelete() im Code. –

1

In der Zeile

IntervalTimemsg = new cMessage("IntervalTimemsg"); 

jedes Mal erstellen eine neue Instanz von cMessage Objekt, und der Zeiger darauf Sie in IntervalTimemsg schreiben. Sie löschen jedoch nie ein Objekt, das von IntervalTimemsg angezeigt wird. Als Folge wird, wenn diese Zeile zweiter ausgeführt (und andere) Zeit:

  • wird ein neues Objekt in dem Speicher erzeugt
  • Der Zeiger auf das vorherige Objekt verloren existiert
  • das vorherige Objekt noch in der Speicher

Deshalb cancelAndDelete(IntervalTimemsg) in finish() nur das letzte Objekt löschen.

Lösungsvorschlag:

  1. Im Konstruktor add:

    IntervalTimemsg = nullptr; 
    
  2. Ändern Sie die Zeile:

    IntervalTimemsg = new cMessage("IntervalTimemsg"); 
    

    in:

    if (IntervalTimemsg != nullptr) { 
        cancelAndDelete (IntervalTimemsg); 
    } 
    IntervalTimemsg = new cMessage("IntervalTimemsg"); 
    
+0

Ich habe bereits den Konstruktor und Destruktor wie du gesagt hast. es hat auch funktioniert, aber immer noch verstehe ich nicht den letzten Schritt, ** 1 ** Ich habe 'cancelEvent (xxxx); 'vor jeder Planung hinzugefügt. ** 2 ** Ich habe jede Nachricht nur einmal erstellt, eine im ersten und die andere in einem Zustand, in dem es nur einmal funktioniert. was ich nicht bekomme ** 3 ** 'if (msg == gateCycleTimemsg) { gateCycleTimemsg = msg; scheduleAt (simTime() + gateCycleTime, gateCycleTimemsg); scheduleAt (simTime() + Intervall, IntervalTimemsg); ' bereits intervalTimemsg wurde empfangen und später gateCycleTimemsg. –

+0

** 1 **) 'cancelEvent()' löscht nur eine Nachricht aus dem zukünftigen Event-Set, und es ** entfernt kein Objekt im Speicher ** ** 2 **) In Ihrem Code eine neue 'cMessage' mit der Name 'IntervalTimemsg' wird jedes Mal ** erzeugt, wenn' gateCycleTimemsg' empfangen wird, zweifellos ** mehr als einmal **. ** 3 **) Die Zeile 'IntervalTimemsg = msg;' ist überflüssig, da 'msg' bereits gleich 'IntervalTimemsg' ist. –