Laufendes Programm finden (Linux / QT)
Laufendes Programm finden (Linux / QT)
Hallo alle miteinander,
heute muss ich mich mal mit einer Frage an das Forum wenden. Meine Suche war leider weniger erfolgreich, habe nur dieses (http://qt-forum.de/forum/viewtopic.php? ... 4bb#p14091) gefunden. Ich erkläre mal das Problem:
Ich habe zwei Programme, die beide auf die seriellen Schnittstellen zugreifen sollen. Nun möchte ich gerne eine Warnung ausgeben, wenn das jeweils andere Programm schon läuft. Das ganze findet unter Linux statt und wird mittels QT3 und c++ geschrieben. Zur Zeit verwende ich ein SharedMEM-Objekt, welches leider bei einem Programmabsturz nicht gelöscht wird. Dadurch kommt dann eben die Meldung, dass das Programm schon läuft.
Kann man irgendwie alle im Fenstermanager vorhandenen Fenster auflisten? Dazu habe ich leider nichts gefunden. Oder irgend was anderes?
QProcess ist auch keine echte Alternative, da ich ja keinen externen Prozess starte.
Ich weiß, QT3 ist schon ganz schön alt, aber das Debian Sarge ist das auch... Ich will das aber nicht unbedingt umstellen.
Viele Grüße
Mirko
heute muss ich mich mal mit einer Frage an das Forum wenden. Meine Suche war leider weniger erfolgreich, habe nur dieses (http://qt-forum.de/forum/viewtopic.php? ... 4bb#p14091) gefunden. Ich erkläre mal das Problem:
Ich habe zwei Programme, die beide auf die seriellen Schnittstellen zugreifen sollen. Nun möchte ich gerne eine Warnung ausgeben, wenn das jeweils andere Programm schon läuft. Das ganze findet unter Linux statt und wird mittels QT3 und c++ geschrieben. Zur Zeit verwende ich ein SharedMEM-Objekt, welches leider bei einem Programmabsturz nicht gelöscht wird. Dadurch kommt dann eben die Meldung, dass das Programm schon läuft.
Kann man irgendwie alle im Fenstermanager vorhandenen Fenster auflisten? Dazu habe ich leider nichts gefunden. Oder irgend was anderes?
QProcess ist auch keine echte Alternative, da ich ja keinen externen Prozess starte.
Ich weiß, QT3 ist schon ganz schön alt, aber das Debian Sarge ist das auch... Ich will das aber nicht unbedingt umstellen.
Viele Grüße
Mirko
Re: Laufendes Programm finden (Linux / QT)
in den qt-solutions
http://code.qt.io/cgit/qt-solutions/qt-solutions.git/
The QtSingleApplication component provides support for applications that can be only started once per user.
http://code.qt.io/cgit/qt-solutions/qt-solutions.git/
The QtSingleApplication component provides support for applications that can be only started once per user.
ODT Informatik GmbH, Reto Tschofenig
Re: Laufendes Programm finden (Linux / QT)
Danke für die schnelle Antwort,
aber wie schon geschrieben, das Ganze soll noch mit QT3 funktionieren. In der Beschreibung steht was von QT5. Leider sind meine Kenntnisse zum Thema QT nicht so toll, ich musste nur dieses Projekt übernehmen. Ich werde es aber mal herunterladen und testen, was unter QT3 passiert. Vorher natürlich noch mal genauer in die Doku sehen...
Viele Grüße
Mirko
aber wie schon geschrieben, das Ganze soll noch mit QT3 funktionieren. In der Beschreibung steht was von QT5. Leider sind meine Kenntnisse zum Thema QT nicht so toll, ich musste nur dieses Projekt übernehmen. Ich werde es aber mal herunterladen und testen, was unter QT3 passiert. Vorher natürlich noch mal genauer in die Doku sehen...
Viele Grüße
Mirko
Re: Laufendes Programm finden (Linux / QT)
technisch hilft dir da eigentlich nicht vieles weiter .... Die single Instance klassen machen eh genau das selbeZur Zeit verwende ich ein SharedMEM-Objekt, welches leider bei einem Programmabsturz nicht gelöscht wird. Dadurch kommt dann eben die Meldung, dass das Programm schon läuft.
im Gegenteil, da den Namen nicht direkt beeinflussen kannst, funktioniert dowas ohne Hacks nur bei instanzen aus der gleichen übersetzungseinheit, und nicht bei unnerschiedlichen Programmen.
wenn du sowas in QApp im constructor/destructor implementierst ... und dein problem auf taucht, dann wird dein destructor nicht aufgerufen ....
da hasst 2 möglichkeiten ...
1. du machst ein "besseres" error/exceptionhandling, damit der destructor auch aufgerufen wird .....
2. du verlässt dich nicht auf QApp sondern registrierst c++ runtime spezifische funktionen für abort/atexit und co (google nach c++ abort handler, atexit()) und so, und räumst da auf ....
Ich will nicht umstellen ist eher ne ganz miese Ausrede ^^ naja eigentlich isses gar keine ^^Ich weiß, QT3 ist schon ganz schön alt, aber das Debian Sarge ist das auch... Ich will das aber nicht unbedingt umstellen.
1. kann man auch unter sarge nen qt5 zum laufen bekommen
2. ist dementsprechend der c++ support vom gcc mies. modern ist anders ..... und der neue standard (c++11 und c++14) ist nen echter Segen
3. wie findet man heutzutage admins die solche ergrauten instanzen warten und dafür auch noch grade stehen ???
Ciao ...Sicherheitsaktualisierungen wurden Ende März 2008 eingestellt.
Re: Laufendes Programm finden (Linux / QT)
Hallo Mirko
Bitte entschuldige, dass ich das Qt3 überlesen habe.
Da Dein Programm unerwartet z.b. durch einen kill -9 beendet werden kann, hilft ein sauberes Exception-Handling nur beschränkt.
Intern arbeitet die Single-Instance mit einem QtLockedFile. Ich glaube, dass QtLockedFile genau Deine Anforderung abdeckt.
http://code.qt.io/cgit/qt-solutions/qt- ... README.TXT
Es wäre ein Versuch wert, ob Du es unter Qt3 zum Laufen kriegst oder ob Du zumindest beim Unix-relevanten Teil spicken kannst.
http://code.qt.io/cgit/qt-solutions/qt- ... e_unix.cpp
Viele Grüsse
Reto
Bitte entschuldige, dass ich das Qt3 überlesen habe.
Da Dein Programm unerwartet z.b. durch einen kill -9 beendet werden kann, hilft ein sauberes Exception-Handling nur beschränkt.
Intern arbeitet die Single-Instance mit einem QtLockedFile. Ich glaube, dass QtLockedFile genau Deine Anforderung abdeckt.
http://code.qt.io/cgit/qt-solutions/qt- ... README.TXT
Es wäre ein Versuch wert, ob Du es unter Qt3 zum Laufen kriegst oder ob Du zumindest beim Unix-relevanten Teil spicken kannst.
http://code.qt.io/cgit/qt-solutions/qt- ... e_unix.cpp
Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig
Re: Laufendes Programm finden (Linux / QT)
Danke noch mal für die Antworten.
Über LockedFiles bin ich jetzt schon mal gestolpert, hatte nur noch keine Zeit, damit zu testen. Das gibt es ja auch schon im c++, also so wie ich es verstehe, auf "Linux-Ebene" Ich konnte es nur noch nicht ausführlich lesen.
Ich müsste nur mal testen, ob dieses Locking noch existiert, wenn der Prozess, der die Datei gesperrt hat, schon gekillt wurde. Das wird aber nicht so schnell gehen, momentan ist die Zeit ziemlich knapp.
Viele Grüße
Mirko
Über LockedFiles bin ich jetzt schon mal gestolpert, hatte nur noch keine Zeit, damit zu testen. Das gibt es ja auch schon im c++, also so wie ich es verstehe, auf "Linux-Ebene" Ich konnte es nur noch nicht ausführlich lesen.
Ich müsste nur mal testen, ob dieses Locking noch existiert, wenn der Prozess, der die Datei gesperrt hat, schon gekillt wurde. Das wird aber nicht so schnell gehen, momentan ist die Zeit ziemlich knapp.
Viele Grüße
Mirko
Re: Laufendes Programm finden (Linux / QT)
Hier kommts drauf an, was bzw. wie das file gelockt wird. Unter Posix/SystemV Systemen gibts ne Handvoll Möglichkeiten ne datei zu sperren. mit jeweils unterschiedlichen verhalten.ob dieses Locking noch existiert, wenn der Prozess, der die Datei gesperrt hat
keine Ahnung auf was die c++ runtime, bzw entsprechende Biblios setzen ...
Aber denk mal unter Linux hasst ne grosse Chance was zu finden, was released wird wenn der process gekillt wird. ^^
Aber ums testen wirst sicher nicht herumkommen ...
Ciao ...
Re: Laufendes Programm finden (Linux / QT)
Hallo noch mal,
Nun hatte ich doch etwas Zeit zum Testen.
Ich habe es jetzt so gelöst:
Die Datei "lockfile" wird auch nur für diesen Zweck benutzt. Ich wollte erst eine Datei nutzen, in der sowieso die Konfiguration gespeichert ist, aber wenn ich die dann später beim Auslesen öffne und schließe, ist auch die Sperre weg. Im Test hat es soweit auch erst mal funktioniert, Die Sperre ist auch weg, wenn ich das Programm kille. Nun werde ich das Ganze mal noch im "produktiven" Programm einbauen. Da kommt dann der Härtetest
Vielen Dank für die Anregungen.
Viele Grüße
Mirko
Nun hatte ich doch etwas Zeit zum Testen.
Ich habe es jetzt so gelöst:
Code: Alles auswählen
int main( int argc, char* argv[] )
{
// initialisierung
QApplication app( argc, argv );
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_WRLCK;
int filehandle = open("/home/kegler/src/bahnwache/lockfile", O_CREAT|O_WRONLY);
int ret = fcntl(filehandle,F_GETLK, &fl);
if(fl.l_type==F_WRLCK)
{
fprintf( stdout, "Schreibsperre gesetzt\n");
return (0);
}
fprintf( stdout, "keine Sperre, weitermachen\n");
fl.l_type = F_WRLCK; //(mode == ReadLock) ? F_RDLCK :
ret = fcntl(filehandle,F_SETLK, &fl);
...
}
Vielen Dank für die Anregungen.
Viele Grüße
Mirko
Re: Laufendes Programm finden (Linux / QT)
Na dann grats ....
100% Linuxer würden die Datei ${ExecutableName}.pid nennen und da ihre ProzessID reinschreiben, damit andere Leute/Prozesse das Lesen können und dem programm Signale schicken können ^^
Ciao ....
Für sowas ist eigentlich das /var/run gut ...Die Datei "lockfile" wird auch nur für diesen Zweck benutzt. Ich wollte erst eine Datei nutzen, in der sowieso die Konfiguration gespeichert ist, aber wenn ich die dann später beim Auslesen öffne und schließe, ist auch die Sperre weg
100% Linuxer würden die Datei ${ExecutableName}.pid nennen und da ihre ProzessID reinschreiben, damit andere Leute/Prozesse das Lesen können und dem programm Signale schicken können ^^
Ciao ....
Re: Laufendes Programm finden (Linux / QT)
Das ist auch nur ein symbolischer Link auf /runFür sowas ist eigentlich das /var/run gut ...
Verlassen darf man sich darauf aber nicht, denn wenn der Prozess gewaltsam getötet wird, bleibt die PID-Datei in der Regel stehen. Das war ja einer der ausschlaggebenden Gründe für die Ablösung von SysV-Init durch systemd. Da die PID-Files den Prozess-Status nicht zuverlässig wiedergeben, schreibt systemd jeden Prozess, den es startet, in eine eigene Control Group, die vom Kernel überwacht wird. Fragt man jetzt nach dem Status des Dienstes, holt sich systemd vom Kernel die Liste der in der jeweiligen Control Group noch laufenden Prozesse. Der Kernel gibt dann entweder genau einen Prozess zurück oder gar keinen ( dann wissen wir verlässlich, dass der Prozess tot ist ).100% Linuxer würden die Datei ${ExecutableName}.pid nennen und da ihre ProzessID reinschreiben, damit andere Leute/Prozesse das Lesen können und dem programm Signale schicken können
Für ein einfaches Programm dürfte das aber wohl etwas zuviel Aufwand sein. Eine Lösung könnte eventuell darin bestehen, dass die Anwendung den Zeitstempel ihres PID-Files in regelmäßigen Abständen aktualisiert. Ist der Zeitstempel eine bestimmte Zeit nicht mehr aktualisiert worden, geht man davon aus, dass der Prozess tot ist. Aber auch das ist nicht ohne Restrisiko.
Re: Laufendes Programm finden (Linux / QT)
Jetzt wird es mir langsam zu kompliziert
Eigentlich geht es nur darum, den Benutzer zu warnen, wenn das Programm (oder ein anderer Teil davon) schon läuft. Die Programmteile kommunizieren über die serielle Schnittstelle mit einem Mikrocontroller. Und es gibt Ärger, wenn man mehrmals auf diese zugreifen will. Mit einem "Schnittstelle xy kann nicht geöffnet werden" kann halt der Benutzer nicht viel anfangen und denkt dann eher, es wäre was kaputt. Wenn da steht "Programm sowieso läuft bereits" ist das irgendwie schicker.
Also noch mal Danke an alle
Viele Grüße
Mirko
Eigentlich geht es nur darum, den Benutzer zu warnen, wenn das Programm (oder ein anderer Teil davon) schon läuft. Die Programmteile kommunizieren über die serielle Schnittstelle mit einem Mikrocontroller. Und es gibt Ärger, wenn man mehrmals auf diese zugreifen will. Mit einem "Schnittstelle xy kann nicht geöffnet werden" kann halt der Benutzer nicht viel anfangen und denkt dann eher, es wäre was kaputt. Wenn da steht "Programm sowieso läuft bereits" ist das irgendwie schicker.
Also noch mal Danke an alle
Viele Grüße
Mirko
Re: Laufendes Programm finden (Linux / QT)
Ja klar ....Verlassen darf man sich darauf aber nicht, denn wenn der Prozess gewaltsam getötet wird, bleibt die PID-Datei in der Regel stehen.
man darf sich aber auch nicht drauf verlassen, dass wenn man ein Signal an nen prozess schickt, das auch gleich das richtige passiert ^^
Theorethisch muesste man sowieso schauen, ob der Prozell lebt und welchen status er hat ....was einfacher geht wenn man die PID schon mal kennt.
und klar mit systemd gehts komplizierter aber dafür auch zuverlässiger ....
Ist auch weniger relevant für dichJetzt wird es mir langsam zu kompliziert
Das war nur ein Hinweis drauf, wie typische Unix Programme/Tools ticken.
DIe brauchen halt ziemlich haeufig die PID von dem Prozess mit dem sie was wollen. Und das ist oft schwer/umständlich zu bekommen.
also relevant für programme die mit anderen kommunizieren ...
und für programme die oft keine oder nur eingeschränkte oberflächen haben ... also auch eh drauf aus sind von extern kontrolliert zu werden^^
Dein test geht auch nicht auf die Existenz von dem Pidfile, sondern aufs Schreibrecht ....
Und das sagt für deine Zwecke ausreichend zuverlässig aus, ob der Prozess noch lebt oder nicht ....
DIe Frage ist dann aber auch ... ist dies die einzige Möglichkeit das was schiefgehen kann ???Und es gibt Ärger, wenn man mehrmals auf diese zugreifen will.
Wenn da wer mit nem anderen Prog auf die Schnittstelle draufhängt, das kriegst mit deiner Lösung nicht abgefangen ....
Da würde dann eh sowas kommen ala "Schnittstelle nicht verfügbar" oder ?
Wenn aber doppelt öffnen die Hauptursache ist, klar kann man das so auch abfangen ... Aber als erfahrenen User iss einem das klar ...
Und der rechner hat oft nicht nur eine serielle Schnittstelle .... früher hatten die minimum 2, oft bis zu 8 hardware und tonnen mehr an virtuellen.
Nen gleichzeitiger/doppelter Betrieb über 2 unterschiedliche Schnittstellen ist keine Option ? Das killst du grad für ne etwas ansprechendere Fehlermeldung ....
Aber klar, wenn das so gewollt ist ..... kommt immer auf die Umgebung an ...
Ciao ....