Laufendes Programm finden (Linux / QT)

Alles rund um die Programmierung mit Qt
Antworten
bornemaxx
Beiträge: 5
Registriert: 27. November 2015 12:52

Laufendes Programm finden (Linux / QT)

Beitrag von bornemaxx »

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
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Laufendes Programm finden (Linux / QT)

Beitrag von odt »

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.
ODT Informatik GmbH, Reto Tschofenig
bornemaxx
Beiträge: 5
Registriert: 27. November 2015 12:52

Re: Laufendes Programm finden (Linux / QT)

Beitrag von bornemaxx »

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
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Laufendes Programm finden (Linux / QT)

Beitrag von RHBaum »

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.
technisch hilft dir da eigentlich nicht vieles weiter .... Die single Instance klassen machen eh genau das selbe
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 weiß, QT3 ist schon ganz schön alt, aber das Debian Sarge ist das auch... Ich will das aber nicht unbedingt umstellen.
Ich will nicht umstellen ist eher ne ganz miese Ausrede ^^ naja eigentlich isses gar keine ^^

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 ???
Sicherheitsaktualisierungen wurden Ende März 2008 eingestellt.
Ciao ...
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Laufendes Programm finden (Linux / QT)

Beitrag von odt »

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
ODT Informatik GmbH, Reto Tschofenig
bornemaxx
Beiträge: 5
Registriert: 27. November 2015 12:52

Re: Laufendes Programm finden (Linux / QT)

Beitrag von bornemaxx »

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
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Laufendes Programm finden (Linux / QT)

Beitrag von RHBaum »

ob dieses Locking noch existiert, wenn der Prozess, der die Datei gesperrt hat
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.
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 ...
bornemaxx
Beiträge: 5
Registriert: 27. November 2015 12:52

Re: Laufendes Programm finden (Linux / QT)

Beitrag von bornemaxx »

Hallo noch mal,
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);
    ...
}
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
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Laufendes Programm finden (Linux / QT)

Beitrag von RHBaum »

Na dann grats ....
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
Für sowas ist eigentlich das /var/run gut ...
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 ....
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: Laufendes Programm finden (Linux / QT)

Beitrag von MichaelS »

Für sowas ist eigentlich das /var/run gut ...
Das ist auch nur ein symbolischer Link auf /run :wink:
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
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 ).

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.
bornemaxx
Beiträge: 5
Registriert: 27. November 2015 12:52

Re: Laufendes Programm finden (Linux / QT)

Beitrag von bornemaxx »

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
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Laufendes Programm finden (Linux / QT)

Beitrag von RHBaum »

Verlassen darf man sich darauf aber nicht, denn wenn der Prozess gewaltsam getötet wird, bleibt die PID-Datei in der Regel stehen.
Ja klar ....
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 ....
Jetzt wird es mir langsam zu kompliziert
Ist auch weniger relevant für dich
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 ....
Und es gibt Ärger, wenn man mehrmals auf diese zugreifen will.
DIe Frage ist dann aber auch ... ist dies die einzige Möglichkeit das was schiefgehen kann ???
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 ....
Antworten