Process.wait() auf Folgeprozesse mitwarten

Status
Nicht offen für weitere Antworten.

guni

Bekanntes Mitglied
hallo,

mit Runtime.exec starte ich in java eine Setup.exe und rufe dann für den Prozess die waitFor-Methode auf. Sinn der ganzen Sache ist, dass mein Java Programm erst weitermachen soll, wenn das setup durch ist.

das Problem ist folgendes:
Setup.exe ruft eine Installer.exe auf. damit endet der Prozess
Installer.exe führt ein paar unzips durch und macht warscheinlich sonst noch ein paar Dinge; entpackt jedenfalls eine komplette JRE und eine Menge Installfiles in einen temporären Ordner. dann ruft er einen javaw-prozess mit einer unmenge an parametern auf und endet damit.
javaw ist vermutlich der prozess, der dann bis zum ende des setups erhalten bleibt.

mein problem ist jedenfalls, dass die setup.exe, die ich urspünglich aufrufe (und auf die ich auch meinen waitFor() ausführe) gleich wieder weg ist.
wie kann ich meinem programm sagen, dass es auch auf die forked processes warten soll?!

mfg, guni
 

guni

Bekanntes Mitglied
gibts einen anderen ansatz, das programm aus java heraus aufzurufen und zu warten, bis es fertig ist?
 
B

Beni

Gast
Vielleicht kannst du zuerst die Konsole (cmd.exe, bash, terminal, ... was immer fuer ein System du hast) aufrufen, und dann ueber die Konsole diese Befehle abschicken? Manchmal ist die Konsole etwas intelligenter als exec.
 

guni

Bekanntes Mitglied
ja ... die idee find ich gar nicht schlecht. mein problem is nur: der installer wird trotzdem in einem eigenen prozess gestartet und damit wüsste dann auch die console nicht, wann sie wieder zugehen soll :-(
 

guni

Bekanntes Mitglied
.. ich hätte da noch einen etwas primitiven Ansatz (gefällt mir gar nicht!) aber zur Not könnte man ihn hernehmen:

Code:
	public void instructSomeWork(String[] foreigner) throws IOException, InterruptedException {
		BufferedReader in = new BufferedReader( new InputStreamReader(System.in) );
		Runtime.getRuntime().exec(foreigner);
		System.out.println("Please press any key when the external process has finished ... ");
		in.readLine();
		in.close();
	}

mein Problem ist:

Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
at java.io.BufferedInputStream.read(BufferedInputStream.java:308)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at com.eurofunk.lesalaire.setup.Layabout.instructSomeWork(Layabout.java:29)
at com.eurofunk.lesalaire.setup.Reviewer.main(Reviewer.java:64)

warum schließt das Programm meinen Stream? Zu der Zeile sollte es doch erst kommen, wenn ich eine Taste gedrückt habe!
 

Leroy42

Top Contributor
guni hat gesagt.:
warum schließt das Programm meinen Stream? Zu der Zeile sollte es doch erst kommen, wenn ich eine Taste gedrückt habe!

Weil du (eventuell) noch vorhrige Zeilenende-Zeichen (die beim letzten read nicht
eingelesen wurden) durch das readLine einliest und dann gleich den Stream closed.
 
S

SlaterB

Gast
vor dem Starten des Prozesses alles noch offene aus dem BufferedReader auslesen,
reader.availabe() hilft vielleicht dabei

----------

in einem Java-Programm sollte es maximal genau einen BufferedReader auf System.in geben,
kannst du als statische Variable ablegen oder so

den System.in-Stream zu closen() scheint mir keinen Sinn zu machen
 

guni

Bekanntes Mitglied
@Slater B:
danke für deine Antwort.
habe meinen BufferedReader global deklariert und in einen Singelton ausgelagert :D

der gedanke, auf den prozess zu warten, lässt mich trotzdem nicht los.
nachdem es mein setup auch unter linux gibt, werde ich mir mal im detail anschauen, welche schritte der installer durchführt, bevor er den eigentlichen installationsprozess ausführt! vielleicht kann ich es dann darauf beschränken und doch einen waitfor einbauen.
jedenfalls danke mal soweit ...

mfg, guni
 

guni

Bekanntes Mitglied
juhuu! ich habe nun doch eine elegante Möglichkeit gefunden, mein problem zu lösen.
das ganze funktioniert deswegen, weil jeder Prozess nur einen einzigen Folgeprozess startet und der Folgeprozess dann interessanterweise die Id jenes Prozesses, der ihn gestartet hat, als Parent ID erhält (obwohl der andere Prozess dann verschwindet).
wie auch immer: das ganze könnte so irgendwie aussehen:

Code:
method ... {
   Process p = Runtime.exec(Programm);
   wait(p.pid);
   ...
}

public void wait(long parent) {
   processlist = getProcessSnapshot(); // CreateToolhelp32Snapshot
   begin: iterate through process list
      if currentprocess.parent == parent {
         currentprocess.waitFor();
         wait(currentprocess.pid);
      }
   end: iterate through process list
}

das problem ist: ich müsste irgendwie mit jni auf die Snapshotfunktion zugreifen und einen Iterate machen!
kann mir da irgendwer helfen?

lg, guni
 
S

Spacerat

Gast
Mit "exec" startet man System-Prozesse über die man keinerlei Einfluss hat. Man kann nur auf dessen Beendigung warten oder dessen Ausgaben lesen. Startet ein solcher Prozess einen weiteren, bekommt die JVM davon auch nichts mit, weil diese ihn eben nicht gestartet hat. Unter Linux kann man die "PID"-Files laufender Prozesse suchen, unter Windows kann man den Taskmanager möglicherweise dazu veranlassen, sich die laufenden Prozesse in der Konsole ausgeben zu lassen (wie z.B. in der Windows2000-Reparatur-Konsole, k.A. ob das noch geht). In einem Java-Thread fragt man das Vorhandensein der betreffenden Einträge ab und lässt sein Programm warten, bis dieser Thread beendet wurde. Ist natürlich alles andere als Systemunabhängig.

mfg Spacerat
 

guni

Bekanntes Mitglied
ja ... ein systemunabhängiges programm zu schreiben habe ich schon aufgegeben.
ich habe auch schon eine möglichkeit gefunden, die PID eines child prozesses zu finden.
fragt sich jetzt nur mehr, wie ich bei gegebener PID ein java Process-Objekt erzeuge, von dem ich dann die wait-Methode aufrufen kann. also irgendwas wie

new Process(PID) ...

geht das?!

mfg, guni
 
S

Spacerat

Gast
Nein...
Baue dir einen Thread, welcher ständig abfragt, ob diese Pid noch vorhanden ist und sich bei nichtmehr Vorhandensein beendet. Dein Hauptprogramm muss nun nur noch solange warten, bis sich dieser Thread beendet hat.

mfg Spacerat
 

guni

Bekanntes Mitglied
hallo spacerat.

mir fehlt dazu ein bisschen der ansatz. ich bin relativ neu in java und threads sind mir generell ein bisschen ein mysterium.
ganz verstehe ich deinen ansatz auch nicht. ok; ich verstehe, dass mein programm nicht auf fremde prozesse, sondern auf den eigenen Thread warten soll. ABER: der thread hat ja gar keine wait-methode! wie mache ich das dann? ausserdem: ist es nicht unschön, den thread in einem zeitintervall abfragen zu lassen, ob ein kindprozess existiert?
genaugenommen müsste der thread immer erst am ende eines prozesses warten!
das würde dann so aussehen:

 

guni

Bekanntes Mitglied
ok ... mir fehlt einfach jeder ansatz! ist da irgendwer, der mir mit ein paar code-ideen aushelfen könnte?!
danke! guni
 

guni

Bekanntes Mitglied
hä? System hat bei mir gar keine sleep-Methode. Und selbst wenn es eine hätte: was würde mir das bringen?!
 

HoaX

Top Contributor
Spacerat hat gesagt.:
Nein...
Baue dir einen Thread, welcher ständig abfragt, ob diese Pid noch vorhanden ist und sich bei nichtmehr Vorhandensein beendet. Dein Hauptprogramm muss nun nur noch solange warten, bis sich dieser Thread beendet hat.

Damit sagt er das gleiche wie du selbst schreibst: Pollen ob der (Unter-)Prozess noch läuft oder nicht. Hat nichts mit auf-einen-Java-Thread-warten zu tun.

Den Aufruf der nativen Methode um den Snapshot zu erstellen machst du am einfachsten per JNA: https://jna.dev.java.net/
Beispiele sind auf der Seite zu genüge, ansonsten frag nochmal speziell nach.

Developer_X hat gesagt.:
Das kannste getrost ignorieren, macht keinen Sinn :)
 

guni

Bekanntes Mitglied
hallo hoax,

jna ist ein tooles stichwort.
mein derzeitiger ansatz war den output von einem ps / wmic / tasklist ... zu parsen ...

na ja - mein problem ist: ich brauch ja trotzdem einen Java-Thread-Wait Funktion ...
weil ich muss ja wissen, zu welchen zeitpunkten ich meinen poll durchführen muss, oder?!

mfg, guni
 
S

Spacerat

Gast
So... wieder da...
Ich hatte mir das shematisch so vorgestellt...
Code:
class Main
{
    Process p = Runtime.getRuntime().exec("externes programm");
    Thread w = new Thread() {
        public void run()
        {
            try {
                // ProzessPids pollen
                while(ProzessPIDs_vorhanden) {
                    // erneut pollen
                    Thread.sleep(500);
                }
            } catch(InterruptedException e) {
                // nothing
            }
        }
    };
    w.start();
    synchronized(w) {
        try{
            w.join();
        } catch(InterruptedException e) {
            // nothing
        }
    }
    //Programm fortsetzen
}

mfg Spacerat
 

guni

Bekanntes Mitglied
hmm ... danke für den ansatz. sysnchronized versteh ich sowieso nicht wirklich; das hab ich mir schon in dem einen oder anderen forum durchgelesen; wirkt aber für mich ziemlich kompliziert (irgendein lock, damit nicht 2 threads auf die gleichen variablen zugreifen oder so ...)
was mich aber mehr stört is ein polling mit sleep! kann ich meine abfrage nicht einfach dann durchführen wenn der beobachtete prozess beendet wird?!
 

guni

Bekanntes Mitglied
@Spacerat ...
ich versteh zwar dein synchronized noch immer nicht ganz aber was solls. Vom Prinzip her schau ich jetzt so halbwegs dahinter ...
trotzdem bringe ich mein Programm noch nicht zum Laufen.
hier nochmal beschrieben, was es können soll:

ich habe mein java-programm rennen.
ich starte irgendwann eine setup.exe mit Runtime.execute
ich ermittle die PID von setup.exe (meine setup.exe forked ein paar prozesse und endet dann)
ich starte einen Thread, dem ich die aktuelle PID übergebe
mein MainThread, muss warten, bis Thread beendet ist

thread sieht so aus:

nichtsgefunden = falsch

wiederhole bis nichtsgefunden = wahr
schlafe (t)
ermittle process snapshot
nichtsgefunden = wahr
durchlaufe process snapshot
wenn aktuellerProzess == parameterpid dann
nichtsgefunden = falsch
wenn aktuellerProzess.parentid == parameterpid
nichtsgefunden = falsch
parameterpid = aktuellerProzess.pid

Hauptprogramm setzt fort, wenn der Thread keinen Kindprozess mehr hat ...
 

HoaX

Top Contributor
den neuen thread kannste vergessen. wenn ich einen neuen thread starte und als nächstes warte bis der fertig ist, dann brauch ich die nebenläufigkeit nicht, also kann ich ihn gleich weglassen und die while-schleife direkt aufrufen.

du bauchst quasi:
Code:
pid = starteSetup();
while(isPidRunning(pid)) {
    Thread.sleep(1000);
}
 
S

Spacerat

Gast
Das synchronized ist notwendig, damit der Hauptthread den Monitor auf den Poller-Thread bekommt, damit "join()" aufgerufen werden kann. Mit "join()" wartet der Hauptthread auf die beendigung des Poller-Threads.
alles was bei dir unterhalb von "mein thread sieht so aus" steht, müsstest du in die while-Schleife meines Poll-Threads bringen. Nun kenn ich weder den Code deines Threads, noch das API mit welchem du an die Parent-IDs kommst (die Process-Klasse aus java.lang verwendest du jedenfalls nicht). "while(ProcessPIDs_vorhanden)" sollte aber Aussagekräftig genug sein. Statt "Thread.sleep()" kann auch "Thread.yield()" verwendet werden.

Was für eine Abfrage willst du eigentlich noch durchführen? Du musst keineswegs wissen, wann du diesen Poll durführen musst, oder besser, dieser Poll muss ständig das Vorhandensein der ProcessPIDs abfragen. Deswegen ist da ja auch eine "while"Schleife. Ich habe da mal zwei Kommentare eingefügt.

@Hoax: Villeicht hilfts, wenn du vorm Antworten das Thema durchliest. Dein Ansatz ist längst Geschichte. :) . Was mir womöglich entgangen ist, ist die Tatsache, das es so villeicht mit "JNA" funzt. Bin ich allerdings auch kein Fan von.

mfg Spacerat
 

Ariol

Top Contributor
Versuch mal ob das bei dir klappt...

Unter Linux geht das:

Code:
		Process p = Runtime.getRuntime().exec("gnome-terminal");
		Field f = p.getClass().getDeclaredField("pid");
		f.setAccessible(true);
		System.out.println( f.get( p ) );
 

guni

Bekanntes Mitglied
@Spacerat
> Villeicht hilfts, wenn du vorm Antworten das Thema durchliest.
> Dein Ansatz ist längst Geschichte.

nein. das denke ich nicht. bis jetzt ist eine Schleife im Hauptprogramm noch nie zur Debatte gestanden. Ich finde diese Art von Abfrage aber trotzdem unschön.
Warum soll ich meinen Programmblock alle paar Millisekunden neu laufen lassen. Ich will ihn doch erst dann durchführen, wenn der Prozess wirklich beendet ist! Kann ich mich von Beendigung eines Prozesses nicht benachrichtigen lassen? Sind die Dinger so unhöflich, dass sie sich im System nicht verabschieden, bevor sie gehn ;-)

@Ariol:
hmm ... mit deinem Ansatz könnte ich theoretisch die ID eines laufenden Prozesses ermitteln. Mein Problem ist aber, dass ich zu einem bestimmten Zeitpunk alle laufenden Prozesse nach ihrem Parentprocess "fragen möchte". Und da hilft mir dein Ansatz eigentlich auch nicht weiter, oder?!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Compiler-Fehler child process exited with code 1 Allgemeine Java-Themen 1
K Threads Runtime und Process Probleme Allgemeine Java-Themen 3
P Herausfinden, ob ein Process ein Fenster hat Allgemeine Java-Themen 1
D Java Process OutputStream ist null Allgemeine Java-Themen 4
X Problem bei process.start() ExitValue Allgemeine Java-Themen 5
T Mit Java auf die Konsole eines Process-Objekts zugreifen Allgemeine Java-Themen 10
P Input/Output Process.getErrorStream = OutputStream Allgemeine Java-Themen 11
J Download: Filename + Process waitFor() Allgemeine Java-Themen 5
S Wie beendet man einen Process in Java Platform unabhänging? Allgemeine Java-Themen 8
M Process wird gestoppt und nach beenden der Anwendung fortgeführt Allgemeine Java-Themen 4
G Process.destory() == CTRL+C Allgemeine Java-Themen 2
P Swing GUI Process anzeigen Allgemeine Java-Themen 10
F Process.getInputStream unter Linux Allgemeine Java-Themen 7
schlingel Process - Ausgabe leer Allgemeine Java-Themen 5
G ungepufferter Process.getInputStream Allgemeine Java-Themen 10
J Process beenden ...aber wie ? Allgemeine Java-Themen 19
G Process - mehrere Commands?! Allgemeine Java-Themen 2
MQue auf gestarteten Process warten Allgemeine Java-Themen 7
P Bedeutung der Process.exitValue() Werte? Allgemeine Java-Themen 3
J Process auf Console anzeigen lassen. Allgemeine Java-Themen 5
S Process - Befehle senden Allgemeine Java-Themen 13
B Process Builder Allgemeine Java-Themen 10
D Thread & Process: Beenden einer Batch-Datei Allgemeine Java-Themen 8
J process.getInputStream() hängt auf merkwürdige Art und Weise Allgemeine Java-Themen 7
D Fremdes Programm schließen (ohne process.destroy()) Allgemeine Java-Themen 8
S process.waitFor() endet mit -1 Allgemeine Java-Themen 3
M Process -> getInputStream -> nur gepuffert ? Allgemeine Java-Themen 12
A Runtime Process bricht nicht ab! Allgemeine Java-Themen 7
C Process output Allgemeine Java-Themen 7
mrbig2017 Threads wait wird nicht durch notify beendet! Allgemeine Java-Themen 3
K Multithreading: Service(Task), wait und continue Allgemeine Java-Themen 21
G Threads Threadprogrammierung wait() und notify() Allgemeine Java-Themen 4
J Thread wait() Allgemeine Java-Themen 2
J Swing Cursor.WAIT funktioniert nicht nach JFileChooser Allgemeine Java-Themen 1
T Wait/Notify() bei Thread Allgemeine Java-Themen 6
A System freezes when trying to run external command from Java with wait for Allgemeine Java-Themen 3
B Threads Barrier mit wait()/notify() aber nicht alle Prozesse terminieren Allgemeine Java-Themen 2
P Threads abwechseln lassen mit wait() und notify() Allgemeine Java-Themen 2
M Java Threads - Wait Notify - Verständnisproblem Allgemeine Java-Themen 5
K Threads wait() und notify() Allgemeine Java-Themen 8
Q Frage zu Threads ( notify() wait() ) Allgemeine Java-Themen 6
G Thread wait, notify Allgemeine Java-Themen 4
T Threadsicheres wait() [lock erst mit wait() abgeben] Allgemeine Java-Themen 31
J synchronized block mit this und wait() Allgemeine Java-Themen 5
H wait() and notify() mit mehreren Prozessen Allgemeine Java-Themen 14
G Thread wait() auf Nicht-Thread Klasse Allgemeine Java-Themen 5
A thread1 stoppt thread2 mit wait() und notify() ? Allgemeine Java-Themen 3
M Thread mit wait anhalten, wie weiterlaufenlassen? Allgemeine Java-Themen 3
M wait in Thread einschieben? Allgemeine Java-Themen 4
C p.wait() bremst aus Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben