2010-07-05 5 views
5

In C++ habe ich eine Ressource, die an eine PID gebunden ist. Manchmal tritt der Prozess, der mit dieser PID verbunden ist, abnormal aus und gibt die Ressource aus.Was ist eine einfache Möglichkeit zu testen, ob ein Prozess einer bestimmten ID derzeit auf Linux läuft?

Daher denke ich daran, die PID in die Datei, die die Ressource aufzeichnet, zu setzen. Wenn ich dann eine Ressource erhalte, wenn ein Element als registriert angezeigt wird, wird es verwendet, um zu sehen, ob gerade ein Prozess läuft, der mit der PID übereinstimmt, und wenn nicht, bereinige die ausgelaufene Ressource.

Ich weiß, dass es eine sehr geringe Wahrscheinlichkeit gibt, dass eine neue nicht freigegebene PID jetzt die gleiche Nummer teilt, aber das ist besser als Lecken ohne Aufräumen, das ich jetzt habe.

Alternativ, vielleicht gibt es eine bessere Lösung dafür, wenn ja, bitte schlagen Sie vor, sonst werde ich die Pid-Aufnahme verfolgen.

Weitere Details: Die Ressource ist eine Portnummer für die Kommunikation zwischen einem Client und einem Server über TCP. Nur eine Instanz des Clients darf eine bestimmte Portnummer auf einem Computer verwenden. Die Portnummern stammen aus einer Reihe von verfügbaren Portnummern, die verwendet werden können. Während der Client ausgeführt wird, notiert er die Portnummer, die er in einer speziellen Datei auf der Festplatte verwendet, und bereinigt diesen Eintrag beim Beenden. Bei einem abnormalen Exit wird dies nicht immer bereinigt und die Portnummer wird mit dem Hinweis versehen, dass sie verwendet wird, wenn sie nicht mehr verwendet wird.

+2

Für welches System möchten Sie dies? Unter Windows wird es anders sein als unter Linux. –

+0

Wenn Sie Linux ausführen, sollten Sie sich das Dienstprogramm pidof ansehen. Wenn du dein eigenes Pid findest, rennst du. –

+0

die Annahme, dass Pid würde es nicht gut wiederholen. es sei denn, Sie haben einen Fall von Tausenden von kurzlebigen Prozessen –

Antwort

4

Um das Vorhandensein des Prozesses mit einer bestimmten ID zu prüfen, verwenden Sie kill(pid,0) (ich nehme an, Sie sind auf dem POSIX-System). Details siehe man 2 kill.

Sie können auch waitpid Anruf verwenden, um benachrichtigt zu werden, wenn der Prozess abgeschlossen ist.

3

Ich würde Ihnen empfehlen, eine Art von OS-Ressource zu verwenden, keine PID. Mutexes, Semaphore, delete-on-close-Dateien. All dies wird vom Betriebssystem bereinigt, wenn ein Prozess beendet wird.

Unter Windows würde ich einen benannten Mutex empfehlen.

Unter Linux würde ich empfehlen, Flock auf eine Datei zu verwenden.

+1

Ich bin mir nicht bewusst, eine Möglichkeit zum Löschen-auf-schließen auf Linux. Beachten Sie, dass Sie eine Datei löschen können, während sie noch geöffnet ist. Sie wird dann gelöscht, wenn der letzte Dateigriff geschlossen wird. Sobald Sie die Datei löschen, können Sie sie natürlich nur noch über einen der vorhandenen Handles abrufen. Dies ist für Sie möglicherweise nicht nützlich. –

+0

Richtig, aber die 'flock' (beratende Sperre für eine Datei) wird freigegeben. Das können andere Prozesse erkennen. Trotzdem würde ich wahrscheinlich auf Romans Vorschlag von 'kill (PID, 0)' gehen oder die Existenz von '/ proc/1234' für PID 1234 überprüfen. (Aber dein Kommentar verwirrte mich ein wenig. Hast du eine Antwort auf a Kommentar, der nachträglich gelöscht wurde?) –

0

Die Problemdomäne ist nicht klar, leider könnten Sie versuchen, es auf eine andere Weise zu erklären.

Aber wenn ich Sie richtig verstehe, können Sie eine Karte wie

std::map< ProcessId, boost::shared_ptr<Resource> > map; 
// `Resource` here references to some abstract resource type 
// and `ProcessId` on Windows system would be basically a DWORD 

und in diesem Fall erstellen Sie haben einfach jeden laufenden Prozess zur Liste und entfernen Sie alle (dies kann über EnumProcesses call unter Windows durchgeführt werden) Eintrag mit unangemessener ID von Ihrem map. Danach hätten Sie nur gültige Prozess-Ressourcen-Paare übrig. Diese Aktion kann je nach Bedarf alle YY Sekunden wiederholt werden.

Beachten Sie, dass in diesem Fall das Entfernen eines Elements aus Ihrer Map im Grunde den entsprechenden Destruktor aufrufen würde (weil, wenn Ihre Ressource nicht in Ihrem Code woanders verwendet wird, der Referenzzähler auf Null fällt).

0

Die API, die erreicht, dass an Fenstern OpenProcess sind, die Prozess-ID als Eingabe und die GetExitCodeProcess STILL_ACTIVE zurücknimmt, wenn der Prozess ist, gut, noch aktiv ist. Sie können auch jede Wait-Funktion mit Null-Timeout verwenden, aber diese API scheint etwas sauberer zu sein.

Wie andere Antworten bemerken, scheint dies jedoch kein vielversprechender Weg zu sein. Wir können möglicherweise gezielter beraten, wenn Sie mehr Szenariodetails bereitstellen. Was ist deine Plattform? Was genau ist die geleakte Ressource? Haben Sie Zugriff auf den Code der undichten App? Kannst du es in eine High-Level-Versuch fangen mit etwas Aufräumen? Wenn nicht, warten Sie vielleicht auf dem Leaker, um mit einem dedizierten Thread (oder dediziertem Prozess) abzuschließen? Jedes von Ihnen bereitgestellte Detail kann helfen.

+0

Weitere Details sind jetzt oben hinzugefügt. – WilliamKF

+0

Also - ist es in der Tat Windows? Ist der genannte Client Teil Ihres Codes? Machen die vorgeschlagenen Alternativen in Ihrem Fall Sinn? –

+0

Da der Titel auf Linux hinweist, bezweifle ich, dass Verweise auf Windows-API-Funktionen hilfreich sind. –

2

Wie sieht es mit einem Master-Prozess aus, der Ihren Prozess startet (der Prozess, der abnormal beendet wird), der darauf wartet, dass Ihr Prozess abstürzt (waitpid) und erneut startet, wenn waitpid zurückkehrt.

while(1) { 
fork exec 
waitpid 
} 
+1

Dies ist der einzige vernünftige Weg, Prozesse zu verwalten, zumindest unter Unix. –

Verwandte Themen