WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Debuggereinstellungen via mfile steuern

 

Lloyd Blankfein
Forum-Century

Forum-Century



Beiträge: 149
Anmeldedatum: 23.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.06.2012, 11:20     Titel: Debuggereinstellungen via mfile steuern
  Antworten mit Zitat      
Hallo

ich starte aus Matlab eine weitere Matlabinstanz:
Code:

system('matlab.exe -r meineanwendung')
 


Ich möchte ein feedback von Instanz 2 haben, für den Fall, dass diese Anwendung mit einer Fehlermeldung abbricht.

Hier meine Idee: Im workspace von Instanz2 gibt es eine Variable "Exception". Wenn es kracht wird diese z.B. mit 1 oder sonst einem Wert gefüllt.

Damit diese Variable auch nach dem crash "sichtbar" bleibt, aktiviert man normalerweise im Editor - Debug - Stop if Errors/Warnings for all Files das flag dbstop if error.
Das möchte / kann ich nicht manuell machen.
Gibt es eine Möglichkeit das über den Code zu steuern?

Letztendlich möchte ich folgendes Verhalten herbeiführen: Instanz1 prüft periodisch ob Instanz2 gecrashed ist. Falls ja, soll Instanz2 abgeschossen und neugestartet werden.
Kann Instantz1 auf den workspace von Instanz2 zugreifen? Hat Matlab eine "SystemID"? Ist es also möglich explizit Instanz 2 abzuschießen?

Vielen Dank für eure Hilfe!
Lloyd
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 27.06.2012, 14:09     Titel: Re: Debuggereinstellungen via mfile steuern
  Antworten mit Zitat      
Hallo Lloyd Blankfein,

Zitat:
Hier meine Idee: Im workspace von Instanz2 gibt es eine Variable "Exception". Wenn es kracht wird diese z.B. mit 1 oder sonst einem Wert gefüllt.

Und wie kann man dann den Inhalt der Variable "Exception" von aussen abfragen? Hier liegt genau das Problem, oder?

Zitat:
Damit diese Variable auch nach dem crash "sichtbar" bleibt, aktiviert man normalerweise im Editor - Debug - Stop if Errors/Warnings for all Files das flag dbstop if error.
Das möchte / kann ich nicht manuell machen.

Zunächst verstehe ich nicht, was "nach dem crash sichtbar" bedeutet.
Was hindert Dich daran "dbstop if error" als Befehl einzugeben bzw. in das Programm zu schreiben?

Es ist im Allgemeinen eine sehr komplizierte Aufgabe von ausserhalb zu testen, ob ein Programm noch läuft oder ob es einen Fehler gab. Es ist deutlich einfacher innerhalb eines Matlab-Programms Fehler abzufangen, indem man den Code in TRY-CATCH einbettet.

Man kann Matlab über die ProcessID von aussen beenden, siehe:
Code:
!tasklist /?
!taskkill /?

Siehe auch "feature('GetPid')".
Trotzdem bin ich davon überzeugt, dass dies eine schlechte Strategie ist. Es ist weitaus stabiler, Crashs zunächst einmal zu vermeiden indem man die Inputs der Funktionen auf Validität überprüft. Und um dann noch Ausnahmen abzufangen wird TRY-CATCH eingesetzt, so dass das Programm immer geordnet beendet wird. Ein Jonglieren mit lokalen Variablen, dem Debugger und TASKKILL ist dagegen wilde Frickelei.

Nebenbei hat das Einschalten des Debug-Modes einige Nachteile: Einerseits schaltet das die JIT-Beschleunigung aus und manche Schleifen können bis zu 1000 mal mehr Zeit benötigen. Und falls Du doch irgendwo ein paar böse EVALs im Code hast, können die Werte sich von Non-Debug-Mode unterscheiden!

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Lloyd Blankfein
Themenstarter

Forum-Century

Forum-Century



Beiträge: 149
Anmeldedatum: 23.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.06.2012, 16:08     Titel:
  Antworten mit Zitat      
Hallo Jan,

Zitat:

Und wie kann man dann den Inhalt der Variable "Exception" von aussen abfragen? Hier liegt genau das Problem, oder?

Ja richtig, die Frage hatte ich weiter oben ja auch gestellt.

Zitat:

Zunächst verstehe ich nicht, was "nach dem crash sichtbar" bedeutet.
Was hindert Dich daran "dbstop if error" als Befehl einzugeben bzw. in das Programm zu schreiben?

Mit "sichtbar", meinte ich, den Zugriff auf den workspace von Instanz2. dbstop if error führt hier zum gewünschten Ergebnis. Danke für den Hinweis.

Tasklist bringt mich leider so nicht weiter. Ich müsste wissen welche PID Instanz2 besitzt.

Zitat:

Es ist weitaus stabiler, Crashs zunächst einmal zu vermeiden indem man die Inputs der Funktionen auf Validität überprüft. Und um dann noch Ausnahmen abzufangen wird TRY-CATCH eingesetzt,

Ganz meine Meinung Wink, das mache ich auch.

Der Fehler der hier auftritt lässt sich m. E. nicht vermeiden:
Ich habe meine Anwendung mit dem Paket von Markus Bühren parallelisiert http://www.mathworks.com/matlabcentral/fileexchange/13775.
Das funktioniert erstmal auch sehr gut. Die Anwendung welche ich geschrieben habe, greift mehrfach mittels read/write auf eine Access-Datenbank zu.
Wenn ich die Anwendung "standalone" durchlaufen lasse, gibt es keine Probleme. Bei der parallelisierten Variante kracht es regelmäßig wenn ich auf die Datenbank zugreife. Da Access keine "echte" DB ist und nicht mit solchen "sich überschneidenden" Abfragen umgehen kann, sehe ich hier keine Möglichkeit den crash zu vermeiden.
Falls das jemand anders sieht. Klärt mich bitte auf!

Deshalb hatte ich die Idee die gecrashde Instanz einfach abzuschießen und erneut zu starten.

Gruß,
Lloyd
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 27.06.2012, 20:08     Titel:
  Antworten mit Zitat      
Hallo Lloyd Blankfein,

Verstehe ich richtig, dass Du auf eine Datenbank mit parallelen Abfragen zugreifst, obwohl diese nicht dafür spezifiziert ist? Und um dies abzufangen, möchtest Du die Clienten neu starten, falls ein Crash (kein ERROR) auftritt?

Würde das nicht bedeuten, dass Du eventuell damit die ganze Datenbank zerschießt?

Das Problem ist es, von der per Shell gestarteten Matlab-Session die ProcessID zu erhalten. Genau das sollte ein Multi-Core-Matlab ja eigentlich leisten, oder?

Du könntest z.B. über http://www.mathworks.com/matlabcent.....change/28572-sharedmatrix ein Message-passing-Interface bauen. Es könnte z.B. nur eine einzige Instanz auf die Datenbank zu zugreifen und die Resultate werden dann per SharedMatrix and die anderen Instanzen verteilt.

Es gibt auch weitere Multi-Core-Matlab Pakete im Netz, aber es bliebe das Problem, eine "gecrashte" Instanz zu erkennen. Wenn sich das Problem nicht per TRY-CATCH abfangen läßt, aber der Crash auch nicht die Matlab-Session autoamtisch beendet, ist eine automatische Erkennung prinzipiell nicht möglich.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Lloyd Blankfein
Themenstarter

Forum-Century

Forum-Century



Beiträge: 149
Anmeldedatum: 23.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.07.2012, 10:23     Titel:
  Antworten mit Zitat      
Hallo Jan,

Zitat:

Verstehe ich richtig, dass Du auf eine Datenbank mit parallelen Abfragen zugreifst, obwohl diese nicht dafür spezifiziert ist? Und um dies abzufangen, möchtest Du die Clienten neu starten, falls ein Crash (kein ERROR) auftritt?

Würde das nicht bedeuten, dass Du eventuell damit die ganze Datenbank zerschießt?


Jein, da das Problem nur beim auslesen der Datenbank auftriit, wird diese auch nicht beschädigt.

Zitat:

Du könntest z.B. über http://www.mathworks.com/matlabcent.....change/28572-sharedmatrix ein Message-passing-Interface bauen. Es könnte z.B. nur eine einzige Instanz auf die Datenbank zu zugreifen und die Resultate werden dann per SharedMatrix and die anderen Instanzen verteilt.


Ich habe etwas ähnliches gebastelt:

Hier wird die PID der aktuellen Instanz in der "shared Matrix" angelegt bzw. geändert. Die shared Matrix ist ein nx2-Array (PID | flag mit Wert 0 oder 1).

Code:

function setPID(varin)

    %check if session.mat exist
    %session.mat stores the PID of all running ModelBuilder sessions
    %if session.mat does not exist, than THIS is the FIRST ModelBuilder sessions
    if exist(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'),'file') > 0
        if varin%overwrite arg2 in sessions, this means session(pos) is marked to be deleted
            sessions=load(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'));
            sessions=sessions.sessions;
            [~,pos]=ismember(feature('getpid'),sessions(:,1));
            sessions(pos,2)=varin;
            save(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'), 'sessions');        
        else
            sessions=load(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'));
            sessions=sessions.sessions;
            sessions(size(sessions,1)+1,1)=feature('getpid');
            sessions(size(sessions,1),2)=varin;
            save(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'), 'sessions');                    
        end
    else%if ession.mat does not exist, create it
        sessions=[feature('getpid'), varin];
        save(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'), 'sessions');
    end

end
 


Hier wird die shared Matrix durchlaufen. Ist der Wert der zweiten Spalte 1, wird die entsprechende Instanz gekillt.

Code:

function cleanPID()

    n=exist(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'),'file');
    if n>0
        sessions=load(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'));
        sessions=sessions.sessions;

        m=1;
        for i=1:size(sessions,1)
            if sessions(i,2)==0
                tmpsessions(m,:)=sessions(i,:);
                m=m+1;
            else%KILL
                %system(cell2mat(strcat({'tskill.exe '},num2str(332))));
                system(cell2mat(strcat({'tskill.exe '},num2str(sessions(i,1)))));
            end
        end

        sessions=tmpsessions;
        save(strcat('C:\Documents and Settings\',getenv('UserName') ,'\My Documents\MATLAB\Modelle+\Persistence\','sessions.mat'), 'sessions');
       
    end

end
 


Das file startmulticoreslave habe ich um folgende Zeilen ergänzt:

Code:

function startmulticoreslave(multicoreDir, settings)

cleanPID();%KILL CRASHED SESSIONS!
setPID(0);%assign pid to THIS session
....

if strcmp(result{k},'error')
     setPID(1);
     system('matlab.exe -r startmulticoreslave');
end
 


Die Funktion, welche von startmulticoreslave aufgerufen wird, hat den Rückgabewert result. Der wird mittels try / catch bestimmt. Für den Fall, das der catch greift wird der Wert 'error' zurückgegeben. Dann bekommt diese Instanz in der "shared matrix" den Wert 1 zugewiesen. Es wird eine weitere Instanz gestartet, welche prüft ob Instanzen existieren die gekillt (flag=1) werden sollen.

Gruß,
Lloyd
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 04.07.2012, 13:01     Titel:
  Antworten mit Zitat      
Hallo Lloyd Blankfein,

Wegen der Übersichtlichkeit würde ich eine Variable benutzen um den langen Pfad-Namen zu speichern, anstatt ihn immer wieder neu zu erstellen.

Und dies kann man vereinfachen:
Code:
system(cell2mat(strcat({'tskill.exe '},num2str(sessions(i,1)))));
% ==>
system(['tskill.exe ',num2str(sessions(i,1))]);
% Oder:
system(sprintf('tskill.exe %d', sessions(i,1)));
 


Bist Du Dir ganz sicher dass ein Crash beim Lesen die Daten nicht verändert? Immer erzeugen effiziente Datenbanken ja einen Cache für häufig ausgelesene Daten. Und wenn dieser bei mehrfachem gleichzeitigen Zugriff zerschossen wird, kann dies auch mit etwas Pech später als Daten-Änderung aufgefasst und zurückgeschrieben werden. Wie immer wäre also ein Backup und regelmäßige Prüfung der Daten-Integrität anzuraten - oder natürlich eine moderne multi-user-fähige Datenbank...

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Lloyd Blankfein
Themenstarter

Forum-Century

Forum-Century



Beiträge: 149
Anmeldedatum: 23.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.07.2012, 14:05     Titel:
  Antworten mit Zitat      
Hallo Jan,

danke für die obigen Hinweise, habe das entsprechend geändert.

Zitat:

Bist Du Dir ganz sicher dass ein Crash beim Lesen die Daten nicht verändert?


Zumindest ist das bisher der Fall gewesen!

Zitat:

Immer erzeugen effiziente Datenbanken ja einen Cache für häufig ausgelesene Daten. Und wenn dieser bei mehrfachem gleichzeitigen Zugriff zerschossen wird, kann dies auch mit etwas Pech später als Daten-Änderung aufgefasst und zurückgeschrieben werden.


Das wusste ich nicht. OK, das so natürlich nicht akzeptabel, ich mach 'nen rollback auf die Standalonevariante.
Schade, soweit hatte Multicorevariante gut funktioniert.
Den übrigen Code habe ich sofern möglich optimiert: Temporäre Variablen, Vektorisierung, wenn vorhanden der Einsatz von mexfiles.
Da mir die toolbox fehlt, kann ich selbst leider keine mexfiles erstellen.

Zitat:

oder natürlich eine moderne multi-user-fähige Datenbank


Ja, schön wärs Sad



Gruß,
Lloyd
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 05.07.2012, 13:18     Titel:
  Antworten mit Zitat      
Hallo Lloyd Blankfein,

Da gibt es noch die Holzhammer-Methode: Wenn die daten nur ausgelesen werden, kopiere die Datenbank-Daten und lasse immer nur ein Datenbank-Programm per Knoten darauf zugreifen.

Natürlich ist das brutal. Aber 2 Festplatten sind billiger als ein doppelt so schneller Prozessor...

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Lloyd Blankfein
Themenstarter

Forum-Century

Forum-Century



Beiträge: 149
Anmeldedatum: 23.02.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.07.2012, 15:26     Titel:
  Antworten mit Zitat      
Hallo Jan,

ich bastel gerade an einer ähnlichen Lösung. Sobald das läuft stell ich den Code rein.

Gruß,
Lloyd
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.