Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Отслеживание состояния запущенного процесса (http://forum.oszone.net/showthread.php?t=90998)

EvgeniyQQQ 27-09-2007 11:33 650361

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

Код:

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


BlackEric 27-09-2007 13:54 650439

Код:

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 650474

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

BlackEric 27-09-2007 16:23 650528

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

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

EvgeniyQQQ 27-09-2007 16:47 650553

Цитата:

Цитата BlackEric
Т.е. у вас Java приложение после вызова waitFor() виснет? »

да
Цитата:

Цитата BlackEric
Приложение которое вы вызываете завершается корректно? »

да
Цитата:

Цитата BlackEric
Если корректно, то waitFor() должен вернуть 0. Что он возвращает? »

Программа как раз на этой функции и весит.
Цитата:

Цитата BlackEric
ОС какая и версия Java? »

ОС Windows XP Pro. Java SDK 1.4, более позднюю версию использовать не желательно.
Цитата:

Цитата BlackEric
<команда для запуска приложения>; - что у вас здесь прописано? »

Путь к вызываемой программе, через пробелы параметры.
Цитата:

Цитата BlackEric
Вы с другим приложением пробовали? »

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

BlackEric 27-09-2007 16:56 650558

Я бы на вашем месте отлаживал это на каком-нибудь Hello Word. T.e. добился корректной работы в минимальном приложении типа
Код:

begin
writeln('vasja');
end.

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

EvgeniyQQQ 27-09-2007 17:40 650584

BlackEric, с Notepad всё работает.

BlackEric 27-09-2007 17:45 650588

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

EvgeniyQQQ 27-09-2007 17:56 650594

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

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

BlackEric, прога GUI. Она выполняет некоторую интеграцию.
Конекты с БД есть. Вот как проверить есть ли утечки памяти не знаю.
Цитата:

Цитата BlackEric
Народ говорит что может быть проблема если интерфейс со скинами.... »

Поясните пожалуйста.

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

BlackEric 27-09-2007 18:18 650610

Цитата:

Цитата EvgeniyQQQ
Цитата BlackEric:
Народ говорит что может быть проблема если интерфейс со скинами.... »
Поясните пожалуйста. »

Опыт он сын ошибок трудных...

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

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

EvgeniyQQQ 01-10-2007 09:43 652236

Вот так:
Код:

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 652359

Првильно, если вы вызываете функцию которая объявлена как synchronized, то пока она не выполнится второй раз ее вызвать нельзя.

EvgeniyQQQ 01-10-2007 14:45 652420

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

BlackEric 01-10-2007 15:50 652457

http://java.sun.com/developer/techni...ing/#Deadlocks
Здесь описано как отлавливать блокировки. Правда для Java 6. Есть ли такое для 1.4 не знаю

EvgeniyQQQ 01-10-2007 18:38 652549

Цитата:

Цитата BlackEric
http://java.sun.com/developer/techni...ing/#Deadlocks »

Статья интересная... но по моему мнению не чем мне помочь не может.

BlackEric 02-10-2007 13:20 652932

В общем как я понял вам нужно для каждого потока для ожидания вызывать метод wait(), а потом когда один поток отработал запускать методом notify() следующий


Время: 03:42.

Время: 03:42.
© OSzone.net 2001-