Внешние программные блоки при запуске из Runtime exec - PullRequest
3 голосов
/ 05 декабря 2009

Я пытаюсь запустить экземпляр программы VideoLAN из Java-приложения. Один из способов, которыми я пытался это сделать, показан здесь:

Process p = Runtime.getRuntime().exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" \"http://www.dr.dk/Forms/Published/PlaylistGen.aspx?qid=1316859&odp=true\" :sout=#std{access=udp,mux=ts,dst=127.0.0.1:63928}");

Если я выполню вышеуказанную команду, программа vlc будет запущена и начнет потоковую операцию (она проходит через этапы подключения, буферизации и затем потоковую передачу).

Когда команда выполняется Runtime exec (или запуском ProcessBuilder), программа vlc зависнет, когда достигнет конца фазы буферизации. Если все потоки в java-программе завершены / запущены до конца, программа vlc перейдет к фазе потоковой передачи. Процесс Java не будет завершен, пока процесс vlc не будет закрыт, поэтому такое поведение, очевидно, является результатом некоторой связи между процессами.

Попытка выполнить команду косвенно, записав ее в файл .cmd и затем выполнив ее, но приводит к тому же поведению.

Есть идеи, как избежать зависания внешнего процесса?

Ответы [ 2 ]

7 голосов
/ 05 декабря 2009

Хм, я думаю, что VLC заполнил ваш буфер STDOUT и завис в инструкции printf, потому что STDOUT ожидает, что этот буфер опустеет.

Вам нужно получить поток для вывода процесса и прочитать его (даже если вы его отбросите).

Я рекомендую вам прочитать эту статью

На 4-й странице приведен хороший пример того, как читать потоки в потоках, чтобы ваш дочерний процесс не блокировался.

0 голосов
/ 05 декабря 2009

Этот сайт просто фантастический :). По какой-то причине подход, который я считал уже испробованным, неожиданно начал работать.

Проблема в том, что vlc пишет в свой stdErrOut (который не отображается при выполнении в приглашении). Затем он блокируется, когда какой-то буфер вывода заполнен. Решение состоит в том, чтобы stdErr перенаправлялся в stdOut, а затем поток очищал входной поток объекта процесса.

Это, однако, не оптимальное решение, так как мне нужно изрядное количество внешних процессов, и вы не можете делать неблокирующие операции ввода-вывода для их входных потоков. Немного поэкспериментируем с тем, чтобы служебный диск таймера читал пустое число процессов. Другие предложения о том, как отключить процессы, чтобы избежать этой проблемы, очень приветствуются.

...