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?
Verfasst am: 27.06.2012, 14:09
Titel: Re: Debuggereinstellungen via mfile steuern
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:
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!
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 PIDInstanz2 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 , 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.
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.
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).
%check if session.matexist
%session.mat stores the PID of all running ModelBuilder sessions
%if session.mat does not exist, than THIS is the FIRST ModelBuilder sessions
ifexist(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
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;
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.
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...
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
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...
ich bastel gerade an einer ähnlichen Lösung. Sobald das läuft stell ich den Code rein.
Gruß,
Lloyd
Einstellungen und Berechtigungen
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
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.