2016-04-11 9 views
0

Ich schreibe ein SDK in Go, mit dem Integratoren über eine lokale Socket-Verbindung kommunizieren.Prozess starten und zu einem späteren Zeitpunkt beenden

Von der integrierenden Anwendung brauche ich eine Möglichkeit, das SDK als Prozess zu starten, aber noch wichtiger, ich muss in der Lage sein, diesen Prozess abzubrechen, wenn die Hauptanwendung ebenfalls geschlossen wird.

Diese Frage ist Sprache agnostisch (ich denke), wie ich denke, die Herausforderung ist Linux bezogen. d.h. wie ein Programm gestartet und zu einem späteren Zeitpunkt abgebrochen wird.

Einige mögliche Ansätze:

  • Ich denke, dass es ein Fall von dem Start des Programms über exec ist, bekommen es ist PID oder eine ID dann, dass später zu töten verwenden. Sudo könnte dazu aufgefordert werden, was nicht ideal ist. Außerdem ist es keine gute Übung, da Sie das SDK effektiv schließen müssen und keine Zeit für die Bereinigung haben.
  • Starten Sie das Programm mit allen Mitteln. Sobald Sie zum Schließen bereit sind, senden Sie einfach einen "shutdown" -Befehl über die SDK-API, der es dem SDK ermöglicht, zu bereinigen, den Status zu verwalten und dann die Anwendung zu beenden.

Was ist Best Practice für diese bitte?

+0

1) Warum sollten Sie 'sudo' einen Prozess zu beenden, die Sie erstellt? Es sollte die gleichen Privilegien des aufrufenden Programms haben. 2) Warum haben Sie "Signale" a priori ausgeschlossen? –

+0

1) Ich war mir nicht sicher, ob Sie Sudo benötigen, um einen Prozess im Allgemeinen zu beenden. 2) Ich bin mir nicht bewusst Signale .. bitte erarbeiten .. – conor

+0

1), soweit ich weiß, keine 2) Da ein Signal, können Sie Setup ein Signal-Handler für sie, das ist eine Funktion, die ausgelöst wird, wenn das Signal wird asynchron über einen Interrupt an den Prozess übergeben. Sie können also ein spezifisches Signal an Ihre Anwendung senden und einen Signal-Handler definieren, der ihn durch die Freigabe seiner Ressourcen sinnvoll beendet. Die Einzelheiten hängen möglicherweise von der Technologie ab, die Sie verwenden (Prozesse, Posix-Threads usw.). Mehr dazu finden Sie hier -> http://man7.org/linux/man-pages/man7/signal.7.html –

Antwort

0

Angenommen, Sie sind mit Linux oder ähnliches Unix:

Sie auf dem richtigen Weg sind. Sie werden kein Sudo brauchen. Die bisherigen Kommentare zeigen in die richtige Richtung, nicht aber die Details.

Einzelheiten zu den hier genannten Funktionen finden Sie in Abschnitt 2 der Handbuchseiten (man 2 ...). Sie sind für den Anruf von C dokumentiert. Ich habe keine Erfahrung mit Go, um festzustellen, wie man sie dort benutzt.

Die Integratoranwendung wird als "Elternprozess" bezeichnet. Das SDK-as-a-Process wird als "Kind" -Prozess bezeichnet. Ein Prozess erstellt ein untergeordnetes Objekt und wird durch Aufruf von fork() zum übergeordneten Element. Der neue Prozess ist ein Duplikat des übergeordneten Elements, das denselben Code ausführt und größtenteils den gleichen Status (Daten im Speicher) aufweist. Aber fork() gibt verschiedene Werte an parent und child zurück, sodass jeder seine Rolle in der Beziehung bestimmen kann. Dies beinhaltet das Informieren der Eltern über die Prozesskennung (pid) des Kinds. Halte an diesem Wert fest. Dann verwendet das Kind exec(), um ein anderes Programm innerhalb des bestehenden Prozesses auszuführen, d. H. Ihre SDK-Binärdatei. Eine Alternative zu fork-then-exec ist posix_spawn(), die eher Parameter enthält (bietet aber mehr Kontrolle, wenn Sie sie brauchen).

Das Entwerfen des untergeordneten Objekts als Reaktion auf ein Signal anstelle eines Befehls über die API ermöglicht es anderen Prozessen als dem übergeordneten Element, sauberes Herunterfahren auf standardmäßige Weise zu initiieren. Dies kann beispielsweise für den Administrator oder Benutzer hilfreich sein. Es ermöglicht das Senden des Shutdown-Signals von der Shell-Befehlszeile oder dem Skript.

Das Kind installiert eine Signal-Handler-Funktion, die aufgerufen wird, wenn der Kindprozess ein Signal empfängt, indem es signal() aufruft (oder die komplexere sigaction(), die für seine Portabilität empfohlen wird). Es gibt verschiedene Signale, die gesendet/empfangen werden können, die durch verschiedene Integer-Werte (und auch Vornamen wie SIGTERM) identifiziert werden. Sie geben an, an welchem ​​Gerät Sie interessiert sind, wenn Sie signal() aufrufen. Wenn Ihre Signal-Handler-Funktion aufgerufen wird, haben Sie das Signal erhalten und können ein sauberes Herunterfahren initiieren.

Wenn der Elternteil möchte, dass das Kind sauber heruntergefahren wird, sendet das Elternteil ein Signal an das Kind mit dem unglücklicherweise benannten kill(). Leider benannt, da Signale für andere Zwecke verwendet werden können.Wie auch immer, Sie übergeben, um() die pid (zurückgegeben von fork()) und das spezifische Signal (z. B. SIGTERM), die Sie senden möchten, zu töten.

Der Elternteil kann auch bestimmen, wann das Kind vollständig durch den Aufruf waitpid() heruntergefahren hat, wieder den von Gabel zurück pid vorbei(); oder alternativ durch Registrieren zum Empfangen des Signals SIGCHLD. Registrieren Sie sich, um SIGCHLD vor fork()/exec() zu empfangen oder Sie verpassen das Signal.

Eigentlich ist es wichtig, dass Sie waitpid() aufrufen, optional nach dem Empfang von SIGCHLD, um eine Ressource mit dem Beendigungsstatus des untergeordneten Prozesses freizugeben, damit das Betriebssystem den letzten Rest des Prozesses bereinigen kann. Anderenfalls bleibt das Kind ein "Zombie" -Prozess, der nicht vollständig zurückgewonnen werden kann. Zu viele Zombies und das Betriebssystem können keine neuen Prozesse starten.

Wenn ein Prozess sich weigert, sauber oder so schnell wie Sie möchten herunterzufahren, können Sie das Beenden des Programms (ohne Ausführung des Bereinigungscodes) erzwingen, indem Sie das Signal SIGKILL senden.

Es gibt Varianten von exec(), waitpid() und posix_spawn(), mit unterschiedlichen Namen und Verhaltensweisen in ihren Mann Seiten erwähnt.

Verwandte Themen