GNU/Linux >> Znalost Linux >  >> Linux

Java ProcessBuilder:Výsledný proces se zablokuje

Chcete to trik?

Nezačínejte proces z ProcessBuilder.start() . Nesnažte se zahrávat si s přesměrováním/spotřebou streamu z Javy (zejména pokud se na to nevykašlete; )

Použijte ProcessBuilder.start() ke spuštění malého skriptu shellu, který pohltí všechny vstupní/výstupní proudy.

Něco takového:

#!/bin/bash

nohup $1 >/dev/null 2>error.log &

To znamená:pokud vás stdout nezajímá a přesto chcete protokol stderr (vy?) do souboru (error.log zde).

Pokud vás ani stderr nezajímá, přesměrujte ho na stdout:

#!/bin/bash

nohup $1 >/dev/null 2>1 &

A zavoláte tomu malému skriptu z Javy a jako argument mu uvedete název procesu, který chcete spustit.

Pokud proces běžící na Linuxu, který přesměrovává stdout i stderr na /dev/null, stále produkuje cokoli pak máte rozbitou, nevyhovující instalaci Linuxu;)

Jinými slovy:výše uvedené prostě funguje [TM] a zbavte se problematického „musíte spotřebovávat streamy v tom a tom pořadí bla bla bla nesmysly specifické pro Javu“ .


Pokud proces zapíše do stderr nebo stdout , a vy to nečtete - prostě se "zasekne" a zablokuje se při zápisu do stdout/err . Buď přesměrujte stdout/err/dev/null pomocí shellu nebo sloučení stdout/err s redirectErrorStream(true) a vytvoří další vlákno, které čte z stdout procesu


Vlákno, na kterém běží proces, se může zablokovat, pokud nezpracovává výstup. To lze provést vytvořením nového vlákna, které přečte výstup procesu.

    final ProcessBuilder builder = new ProcessBuilder("script")
                    .redirectErrorStream(true)
                    .directory(workDirectory);

    final Process process = builder.start();
    final StringWriter writer = new StringWriter();

    new Thread(new Runnable() {
        public void run() {
            IOUtils.copy(process.getInputStream(), writer);
        }
    }).start();

    final int exitValue = process.waitFor();
    final String processOutput = writer.toString();

Linux
  1. Jak se začít učit programovací jazyk

  2. Nainstalujte Oracle Java 16 na Ubuntu 18.04 / 20.04 / 21.04 - Postup krok za krokem?

  3. Instalace Javy na systém Debian 9 – proces krok za krokem?

  1. Začít proces na jiném Tty?

  2. linuxový skript pro zabití procesu Java

  3. Rostoucí využití rezidentní paměti (RSS) Java Process

  1. Jak zjistím, který běžící proces používá javu?

  2. změnit /proc/PID/environ po spuštění procesu

  3. Jak seřadit výstup ps podle času zahájení procesu?