[JAVA] Kinx Library - Prozess

Kinx Library - Prozess

Einführung

** "Sieht aus wie JavaScript, Gehirn (Inhalt) ist Ruby, (Stabilität ist AC / DC)" ** Skriptsprache Kinx ). Die Sprache ist die Bibliothek. Also, wie man die Bibliothek benutzt.

Diese Zeit ist Prozess. Ich habe es eilig gemacht, weil es notwendig war, einen Kinderprozess zu starten.

System.exec()

Eine Befehlsausführungsschnittstelle, die seit langem als Standard vorbereitet ist. Es ist einfach, weil es einfach "system ()" auf der C-Ebene aufruft, aber es ist unpraktisch, weil es nicht zurückkommt, bis es fertig ist, oder weil es nicht die Standardausgabe erhalten kann. Da der Befehl jedoch über die Shell ausgeführt wird, können Weiterleitungen verwendet werden.

Also habe ich dieses Mal eine "Prozess" -Klasse erstellt, die mehr kann, und das ist der Favorit in dieser Erklärung.

Process

using Process

Die Prozessbibliothek ist nicht integriert. Verwenden Sie daher die using-Direktive, um sie explizit zu laden.

using Process;

Exec

Das Process-Objekt wird mit new Process (Befehl, Optionen) erstellt. Das Argument ist ein Befehlsname und ein Array von Argumenten oder eine Befehlszeichenfolge. Im Fall eines Arrays scheint es, als würden die Argumente separat übergeben, und im Fall einer Befehlszeilenzeichenfolge wird sie intern analysiert und automatisch in ein Array-Format zerlegt.

Das erstellte Prozessobjekt verfügt über die folgenden Methoden.

Methode Überblick
run() Starten Sie den Prozess.
launch() Starten Sie den Prozess und trennen Sie die Verbindung.
std() Die als Argumente übergebenen Optionen werden zurückgegeben.
{ in: opts.in, out: opts.out, err: opts.err }

Zu diesem Zeitpunkt noch nicht ausgeführt. Es startet, wenn "run ()" oder "launch ()" ausgeführt wird. run () gibt ein Objekt der Klasse ProcessController zurück.

Run

run () gibt ein Objekt der Klasse ProcessController zurück.

var p = new Process(["cmd","arg1"]).run();

Launch

launch () gibt nichts zurück (oder eher null). Die Methode besteht darin, sich nach dem Herausschieben nicht um das Kind zu kümmern.

new Process(["cmd","arg1"]).launch();

ProcessController

Die von "run ()" zurückgegebene "ProcessController" -Klasse verfügt über die folgenden Methoden.

Methode Überblick
isAlive() True, wenn der Prozess aktiv ist, wenn er bereits beendet wurde, oderdetachFalsch, nachdem Sie fertig sind
wait() Wartet auf das Ende des Prozesses und gibt nach dem Ende den Endcode des Prozesses zurück.detachDann wird 0 zurückgegeben.
detach() Trennen Sie den Prozess

remove () wird nach dem Start des Prozesses getrennt. Unter Linux unterscheidet sich der Vorgang geringfügig vom Fall des Trennens mit "launch ()", aber Sie möchten dasselbe tun. Der interne Vorgang ist unter Windows identisch.

Unter Linux wird die sogenannte ** Double-Fork ** -Methode verwendet, um die Verbindung zu trennen, wenn der Prozess gestartet wird. Dies kann jedoch nur verwendet werden, wenn der Prozess gestartet wird. Es ist praktisch unmöglich, die Verbindung nach dem Starten eines Prozesses zu trennen, und wenn der übergeordnete Prozess nicht richtig "wartet" oder "wartet", überlebt das Kind als Zombie.

Im Moment von remove () starte ich einen Thread nur für waitpid und kümmere mich darum, bis das Kind stirbt.

Double-Fork ist übrigens Linux,

Mit der Funktion ... können Sie den Prozess nach dem Verzweigen verzweigen, dann den ersten gegabelten Prozess in Eile beenden und init den Enkelprozess verwalten lassen.

Der oberste übergeordnete Prozess merkt sich die Wartezeit des ersten gegabelten Kindes. Mein Enkel ist derjenige, der sich um mich kümmert.

Wait

Das Folgende ist ein Beispiel für das Warten auf das Ende und das Abrufen des Endcodes.

var p = new Process(["cmd", "arg1"]).run();
var status = p.wait();

Wenn Sie "Trennen" haben, können Sie es natürlich nicht bekommen (0 wird zurückgegeben).

Detach

Das "Ablösen", das früher herauskam. Der Prozess kann auch "trennen" sein. Wenn Sie es trennen, wird die Verbindung mit dem Kind unterbrochen. Sie müssen nicht warten und sich keine Sorgen um das Ende machen. Oder besser gesagt, Sie können es nicht tun, selbst wenn Sie sich darüber Sorgen machen möchten.

var p = new Process(["cmd", "arg1"]).run();
p.detach();

Pipe

Ich warte auf die Pfeife. Der Hauptzweck der Erstellung von "Prozess" ist die Pipe. Die am meisten gewünschte Funktion besteht darin, die Standardeingabe / -ausgabe mit dem untergeordneten Prozess frei mit einer Pipe zu verbinden, um Informationen auszutauschen.

Die Pipe wird durch "opts" von "new Process (cmd, opts)" angegeben. Es gibt drei Arten von Parametern:

Parameter Inhalt
in Geben Sie die Standardeingabe an.
Sie können ein Pipe-Objekt, eine Zeichenfolge,$stdin
out Geben Sie die Standardausgabe an.
Sie können ein Pipe-Objekt, eine Zeichenfolge,$stdoutOder$stderr
err Geben Sie die Standardfehlerausgabe an.
Sie können ein Pipe-Objekt, eine Zeichenfolge,$stdoutOder$stderr

Rohrobjekt

Pipe-Objekte werden mit new Pipe () erstellt. Gibt ein Array von zwei Objekten, "[Lesen, Schreiben]", paarweise zurück. Das Pipe-Objekt verfügt über die folgenden Methoden.

Normalerweise wird die "Write" -Pipe als "out" oder "err" des untergeordneten Prozesses angegeben und aus der "Read" -Pipe gelesen.

Read Pipe

Schließen Sie das Rohr nach run (). Weil es gesetzt ist, wenn run () fertig ist.

Methode
peek() Gibt 0 zurück, wenn keine Daten in der Pipe vorhanden sind, größer als 0, wenn vorhanden.-1 ist ein Fehler.
read() Holen Sie sich alle Pipe-Daten als String. Wenn keine Daten vorhanden sind, wird eine leere Zeichenfolge zurückgegeben.
close() Schließen Sie das Rohr.

Write Pipe

Schließen Sie das Rohr nach run (). Weil es gesetzt ist, wenn run () fertig ist.

Methode
write(data) Schreiben Sie Daten in die Pipe. Es können nicht alle geschrieben werden, und die Anzahl der geschriebenen Bytes wird zurückgegeben.
close() Schließen Sie das Rohr.
Stichprobe

Die allgemeine Form wird wie folgt verwendet.

using Process;

var [r1, w1] = new Pipe();
var p1 = new Process([ "ls", "-1" ], { out: w1 }).run();
w1.close(); //Ich benutze es nicht mehr, damit du es schließen kannst
while (p1.isAlive() || r1.peek() > 0) {
    var buf = r1.read();
    if (buf.length() < 0) {
        System.println("Error...");
        return -1;
    } else if (buf.length() > 0) {
        System.print(buf);
    } else {
        // System.println("no input...");
    }
}
System.println("");

Wenn Sie Write Pipe auf der übergeordneten Prozessseite verwenden, sieht es so aus.

using Process;

//stdin liest von der Pipe und gibt die Standardausgabe aus
[r1, w1] = new Pipe();
var p1 = new Process("cat", { in: r1, out: $stdout }).run();
r1.close(); //Ich benutze es nicht mehr, damit du es schließen kannst

//Senden Sie an stdin auf p1
var nwrite = w1.write("Message\n");
w1.close(); //Rohr schließen, Getriebeende

p1.wait();

Auf diese Weise können Sie übrigens die Standardausgabe und die Standardfehlerausgabe steuern.

new Process("cmd", { out: $stdout, err: $stdout }); //Standardfehlerausgabe mit Standardausgabe zusammenführen
new Process("cmd", { out: $stderr, err: $stderr }); //Standardausgabe mit Standardfehlerausgabe zusammenführen
new Process("cmd", { out: $stderr, err: $stdout }); //Tauschen

Pipeline

Das Anschließen von Rohren ist eine ziemlich mühsame Aufgabe (oder besser gesagt, welche ist ...?). Deshalb habe ich auch "Process.pipeline" definiert, was alles auf einmal erledigt. Zum Schluss setzen Sie eine Rückruffunktion und verwenden Sie sie wie folgt.

var r = Process.pipeline(cmd1, cmd2, cmd3, ..., &(i, o, pipeline) => {
    // i ...Schreiben Sie die Pipe für den ersten Befehl an stdin
    // o ...Lesen Sie die Pipe aus dem Standard des letzten Befehls
    // pipeline ...Pipeline-Objekt
    //    pipeline.input .......Gleich wie ich oben
    //    pipeline.output ......Gleich wie oben
    //    pipeline.peek() ...... pipeline.output.peek()Gleich wie
    //    pipeline.read() ...... pipeline.output.read()Gleich wie
    //    pipeline.write() ..... pipeline.input.write()Gleich wie
    //    pipeline.isAlive() ...True, wenn ein Prozess in der Pipeline aktiv ist
    //    pipeline.wait() ......Warten Sie, bis alle Prozesse in der Pipeline abgeschlossen sind.
    //Gibt den Endcode als Array zurück

    //Der Rückgabewert des Rückrufs bleibt unverändert.pipeline()Es wird der Rückgabewert von.
    return pipeline.wait();
});

Sie können es verwenden, ohne zurückzurufen.

var pipeline = Process.pipeline(cmd1, cmd2, cmd3, ...);
// pipeline ...Pipeline-Objekt
//Unten weggelassen.

abschließend

Die untergeordnete Prozessbeziehung unterscheidet sich zwischen Windows und Linux. Daher ist es ein guter Punkt des Skripts, solche Dinge auf einheitliche Weise behandeln zu können. Die Befehle selbst sind jedoch unterschiedlich, so dass es schwierig ist, sie zu absorbieren. Ich bin ein Windows-Benutzer, verwende jedoch UnxUtils, um einige Unix-Befehle auch an der Eingabeaufforderung verfügbar zu machen. (Ich mag Cygwin nicht wirklich, weil es die Umgebung verändert ...)

Also nächstes Mal.

Recommended Posts

Kinx Library - Prozess
Kinx-Bibliothek - Getopt
Kinx Library-JIT-Compiler-Bibliothek
Kinx Library-JIT-Compiler-Bibliothek (Extra Edition)