PDA

Показать полную графическую версию : Отслеживание состояния запущенного процесса


EvgeniyQQQ
27-09-2007, 11:33
Добрый день! Пишу программу на Java. Которая должна вызывать другую программу из своего кода. Далее моя программка должна дождаться когда запущенный ею процесс завершится. Проблема заключается в том, что стандартной функцией waitFor() отследить завершение процесса не удаётся.
Подскажите пожалуйста. Можно ли средствами Java отследить завершение процесса (написать диспетчер задач)?


Runtime runtime = Runtime.getRuntime();
Process p = null;
String cmd = <команда для запуска приложения>;
p = runtime.exec(cmd);
p.waitFor(); //заставляет приложение ждать (приостановить своё выполнение) пока не выполнится запущенный процесс

BlackEric
27-09-2007, 13:54
public boolean runProgramAndWait(String runCommand){
Process process;
java.lang.Runtime runtime;
try{
runtime = Runtime.getRuntime();
process = runtime.exec(runCommand);
process.waitFor();
return true;
}catch (InterruptedException e){
return false;
}
catch (Exception e){
return false;
}
}

Вот так должно работать.

EvgeniyQQQ
27-09-2007, 14:23
BlackEric, я так и сделал, но не работает. Возможно, то приложение, которое я вызываю, завершившись, оставляет после себя что то, что свидетельствует для waitFor() о его присутствии.

BlackEric
27-09-2007, 16:23
Т.е. у вас Java приложение после вызова waitFor() виснет?
Приложение которое вы вызываете завершается корректно?
Если корректно, то waitFor() должен вернуть 0. Что он возвращает?
ОС какая и версия Java?

<команда для запуска приложения>; - что у вас здесь прописано?
Вы с другим приложением пробовали?

EvgeniyQQQ
27-09-2007, 16:47
Т.е. у вас Java приложение после вызова waitFor() виснет? »
да
Приложение которое вы вызываете завершается корректно? »
да
Если корректно, то waitFor() должен вернуть 0. Что он возвращает? »
Программа как раз на этой функции и весит.
ОС какая и версия Java? »
ОС Windows XP Pro. Java SDK 1.4, более позднюю версию использовать не желательно.
<команда для запуска приложения>; - что у вас здесь прописано? »
Путь к вызываемой программе, через пробелы параметры.
Вы с другим приложением пробовали? »
Нет. Мысль хорошая.

Приложение которое я вызываю написано на Delphi.

BlackEric
27-09-2007, 16:56
Я бы на вашем месте отлаживал это на каком-нибудь Hello Word. T.e. добился корректной работы в минимальном приложении типа

begin
writeln('vasja');
end.

, а потом запускал работу с вашей прогой.

EvgeniyQQQ
27-09-2007, 17:40
BlackEric, с Notepad всё работает.

BlackEric
27-09-2007, 17:45
Вывод: Java - код рабочий.
Что делает дельфовая прога? Она консольная или с GUI?
Нет ли утечек памяти, не закрытых файлов, коннектов к БД и прочая?
Народ говорит что может быть проблема если интерфейс со скинами....

EvgeniyQQQ
27-09-2007, 17:56
BlackEric, спасибо. Вроде всё заработало сам не понимаю почему. Хотя ПК слабенькие. Я дождался когда процесс исчезнет в диспетчере задач, но возможно нужно было ещё подождать, что бы процесс выгрузился полностью (может он еще не успел это сделать).

Правда, возникла ещё одна проблема. Моё приложение создаёт потоки, каждый из которых на некотором этапе своего исполнения вызывают функцию общего класса, при этом блокируя (запирая) этот класс (запрещая вызов функции другими процессами). Они в свою очередь ждут пока эта функция освободиться. В этой функции как раз и запускается внешний процесс. Вопрос в том, что функция waitFor() почемуто заставляет ждать всё приложение (а не отдельный поток) пока выполнится внешний процесс.

BlackEric, прога GUI. Она выполняет некоторую интеграцию.
Конекты с БД есть. Вот как проверить есть ли утечки памяти не знаю.
Народ говорит что может быть проблема если интерфейс со скинами.... »
Поясните пожалуйста.

Я обрадовался, что всё заработало, на самом деле получается через раз.

BlackEric
27-09-2007, 18:18
Цитата BlackEric:
Народ говорит что может быть проблема если интерфейс со скинами.... »
Поясните пожалуйста. »
Опыт он сын ошибок трудных...

Как проверять наличие утечек памяти в Delphi посмотрите в гугле.

Как объявлена функция которая блокируется и класс в котором она находится?

EvgeniyQQQ
01-10-2007, 09:43
Вот так:

class Mon
{
public Mon()
{

}

public synchronized void Run(String cmd, int i)
{
try
{
Runtime runtime = Runtime.getRuntime();
Process p = null;

String nStream = " Stream (" + i + ") Run: [" + cmd + "]...";
System.out.print(nStream);

p = runtime.exec(cmd);

if (p.waitFor() == 0)
{
System.out.print(" ok");
}
else System.out.print(" error");

}
catch (Exception e) { e.printStackTrace(); }
}
}

BlackEric
01-10-2007, 12:59
Првильно, если вы вызываете функцию которая объявлена как synchronized, то пока она не выполнится второй раз ее вызвать нельзя.

EvgeniyQQQ
01-10-2007, 14:45
BlackEric, всё так и задумано. Вопрос в том, что когда я вызываю эту функцию из потока, она в свою очередь вызывает внешний модуль. Функция waitFor() заставляет приложение ждать пока внешний модуль выполнится. Но, мне нужно, что бы эта функция заставляла ждать только тот поток который в данный момент получил доступ к public synchronized void Run(String cmd, int i).
Иначе говоря, мне нужно организовать очередь в которую будут попадать потоки желающие вызвать внешний модуль. Нельзя, чтобы его вызывали сразу два потока.

BlackEric
01-10-2007, 15:50
http://java.sun.com/developer/technicalArticles/J2SE/monitoring/#Deadlocks
Здесь описано как отлавливать блокировки. Правда для Java 6. Есть ли такое для 1.4 не знаю

EvgeniyQQQ
01-10-2007, 18:38
http://java.sun.com/developer/techni...ing/#Deadlocks »
Статья интересная... но по моему мнению не чем мне помочь не может.

BlackEric
02-10-2007, 13:20
В общем как я понял вам нужно для каждого потока для ожидания вызывать метод wait(), а потом когда один поток отработал запускать методом notify() следующий




© OSzone.net 2001-2012