java - про Process
Process proc=null;
try{
proc = Runtime.getRuntime.exec("c:\\a.exe");
}catch(IOException e){}
Thread.sleep(5000 * 60);
try{
int result = proc.exitValue;
// пишем время
} catch(IllegalThreadStateException e) {
proc.destroy;
// пишем, что плохо
}
Как-то так... В любом случае, почитай http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Process.ht... - про exitValue особенно.
try{
proc = Runtime.getRuntime.exec("c:\\a.exe");
}catch(IOException e){}
Thread.sleep(5000 * 60);
try{
int result = proc.exitValue;
// пишем время
} catch(IllegalThreadStateException e) {
proc.destroy;
// пишем, что плохо
}
Как-то так... В любом случае, почитай http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Process.ht... - про exitValue особенно.
you wrote
Process proc=null;
try{
proc = Runtime.getRuntime.exec("c:\\a.exe");
}catch(IOException e){}
Thread.sleep(5000 * 60);
try{
int result = proc.exitValue;
// пишем время
} catch(IllegalThreadStateException e) {
proc.destroy;
// пишем, что плохо
}
Как-то так... В любом случае, почитай http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Process.ht... - про exitValue особенно.
Так не правильно . Втаком случае текущий нить(current Thread) всегда ждёт 5 минут.
Если время выполнения pro только 2 секунды, тогда программа выводит 5 минут ? (не правильно)
подумаю, что надо использовать method wait(. но не знаю как правильно
Можно
boolean badExit = True;
while(не_прошло_5_мин){
try{
int result = proc.exitValue;
// пишем время
badExit = False;
break;
} catch(IllegalThreadStateException e) {}
}
if(badExit){
proc.destroy;
// нишем, что всё плохо
}
boolean badExit = True;
while(не_прошло_5_мин){
try{
int result = proc.exitValue;
// пишем время
badExit = False;
break;
} catch(IllegalThreadStateException e) {}
}
if(badExit){
proc.destroy;
// нишем, что всё плохо
}
Проверил. Вот это работает:
import java.io.IOException;
public class Proc {
public static void main(String[] args) throws InterruptedException {
Process proc=null;
try{
proc = Runtime.getRuntime.exec("notepad");
}catch(IOException e){}
boolean badExit = true;
long maxTime = 1000000000;// 1 секунда
maxTime *= 300; // 5 минут
long startTime = System.nanoTime;
long curTime = System.nanoTime;
while(curTime - startTime < maxTime){
try{
int result = proc.exitValue;
System.err.println("Время " + (curTime - startTime) / 1000000 + " мсек");
badExit = false;
break;
} catch(IllegalThreadStateException e) {}
curTime = System.nanoTime;
}
if(badExit){
proc.destroy;
System.err.println("Всё плохо");
}
}
}
посмотрю
Зачем цикл?
public class ProcessTest
{
public static void main(String args[])
{
try {
Timer timer = new Timer(true);
final Thread mainThread = Thread.currentThread;
long timeBegin = System.currentTimeMillis;
final Process process = Runtime.getRuntime.exec("calc.exe");
timer.schedule(new TimerTask {
public void run {
mainThread.interrupt;
process.destroy;
}
}, 5*60*1000);
int result = process.waitFor;
timer.cancel;
mainThread.interrupted;
System.out.println("Process has exit with code " + result + " after " +
(System.currentTimeMillis - timeBegin) + " milliseconds.");
}
catch (InterruptedException e) {
System.out.println("Process didn't exit in 5 minutes.");
}
catch (Exception e) {
System.out.println("Error.");
}
}
}
Если процесс завершится сам чуть-чуть раньше таймера, то mainThread сможет начать уже что-то печатать про время, а тут таймер его прибьёт.
Race condition, однако.
Race condition, однако.
Да, исправил.
Ничё не исправил.
Например, waitfor уже сработал, а timer.cancel ещё нет, и тут оно как жахнет...
Например, waitfor уже сработал, а timer.cancel ещё нет, и тут оно как жахнет...
Ну и выведется
"Process didn't exit in 5 minutes.", что не так далеко от истины.
"Process didn't exit in 5 minutes.", что не так далеко от истины.
Может, выведется, а может, и не успеет, если TimerTask.run уже запущено оказалось - timer.cancel его не срубит.
Я думаю, очевидно корректный метод примерно такой: создаётся два треда, один ждёт процесс, другой ждёт таймера.
Который первый дожидается, сигналит основному треду (хз, какие для этого средства в яве - нужен какой-нибудь message queue; можно сигналить через разделяемый объект, тогда дополнительное место для бага, если неосторожно сделать).
Основной тред получает сообщение, срубает оба треда.
Если успевает прийти два сообщения, то учитывать только первое.
Код написать не могу, могу только на C под POSIX попробовать аналог сделать.
Который первый дожидается, сигналит основному треду (хз, какие для этого средства в яве - нужен какой-нибудь message queue; можно сигналить через разделяемый объект, тогда дополнительное место для бага, если неосторожно сделать).
Основной тред получает сообщение, срубает оба треда.
Если успевает прийти два сообщения, то учитывать только первое.
Код написать не могу, могу только на C под POSIX попробовать аналог сделать.
Ну если не успеет, выведется "Process has exit with code ..." что также можно считать правдой.
Не так. Эта строчка может вывестись целиком, или вообще не до конца (атомарность System.out.println кто-нибудь обещает?).
А потом выведется "Process didn't exit in 5 minutes."
А потом выведется "Process didn't exit in 5 minutes."
Неа. System.out.println нельзя прервать interrupt'oм. Можно прервать только waitfor.
> System.out.println нельзя прервать interrupt'oм.
А вдруг там внутри I/O через InterruptibleChannel?
Ну а если не прервёт, к чему тогда приведёт interrupt flag - тут моих знаний не хватает?
А вдруг там внутри I/O через InterruptibleChannel?
Ну а если не прервёт, к чему тогда приведёт interrupt flag - тут моих знаний не хватает?
да, красивое решение.
есть другое без Timer ?
есть другое без Timer ?
Даже в списке исключений, кидаемых PrintStream.println(String x) нет InterruptedException.
Ну всё равно interrupt flag останется у треда, на что он повлияет?
При следующем вызове sleep/waitFor/... немедленно выкинет InterruptedException.
ну значит, есть баг, так как в доке не написано, что этот код может нарушить работу след. вызова
Можно и без Timer (но со второй нитью)
По поводу цикла ожидания - не уверен, что нужен, но лишним не будет (тот же Object.wait(long millis) может прерываться "просто так")
import java.io.IOException;
public class test {
static final String CALC = "c:\\winnt\\system32\\calc.exe";
static final long timeout = 5 * 60 * 1000;
static class ProcUtil implements Runnable {
boolean completed = true;
int retcode;
Process p;
ProcUtil(String pname) throws IOException {
p = Runtime.getRuntime.exec(pname);
}
public void run {
while (true) {
try {
retcode = p.waitFor;
completed = true;
return;
} catch (InterruptedException e) {}
}
}
void kill {
p.destroy;
}
}
public static void main(String [] args) {
ProcUtil p;
try {
p = new ProcUtil(CALC);
} catch (IOException bugs) {
bugs.printStackTrace;
return;
}
long ctime = System.currentTimeMillis;
long etime = ctime + timeout;
Thread ct = new Thread(p);
ct.start;
while (ctime < etime && ct.isAlive {
try {
ct.join(etime - ctime);
} catch (InterruptedException e) {
}
ctime = System.currentTimeMillis;
}
if (ct.isAlive {
p.kill;
System.err.println("Killed");
} else {
System.err.println("All OK");
}
}
}
По поводу цикла ожидания - не уверен, что нужен, но лишним не будет (тот же Object.wait(long millis) может прерываться "просто так")
В .Net 2.0 будет примерно так:
Process newProcess = Process.Start("c:\\a.exe");
if (newProcess.WaitForExit(5 * 60 * 1000
Console.WriteLine("It took " + newProcess.TotalProcessorTime);
else
newProcess.Kill;
ну значит, есть баг, так как в доке не написано, что этот код может нарушить работу след. вызоваНу вообще процесс прерывания потоков описан вполне детально. В данном случае всё будет нормально работать. Тут ведь речь идёт не об уничтожении потока, а именно о сигнале прерывания внутри java.
PS Я даже зря написал timer.cancel не подумав.
> а именно о сигнале прерывания внутри java
у тебя этот сигнал останется по завершении фрагмента, и баг проявится
где-то далее по треду (что ещё хуже, чем если бы он проявился сразу)
у тебя этот сигнал останется по завершении фрагмента, и баг проявится
где-то далее по треду (что ещё хуже, чем если бы он проявился сразу)
у тебя этот сигнал останется по завершении фрагмента, и баг проявитсяУ меня программа выйдет. Так что нигде баги не проявятся. Если тебе требуется пример фукнции, делающей всё тоже самое, я могу его написать.
где-то далее по треду (что ещё хуже, чем если бы он проявился сразу)
Оставить комментарий
stat5257402
у меня есть ворос про Process.создал один Process так,
Process proc=null;
try{
proc = Runtime.getRuntime.exec("c:\\a.exe");
}catch(IOException e){}
вопрос состоит в том, что дописать программу чтобы выполнить следующие требования:
1)если время выполнения Process pro больше 5 минут, то остановить его и destroy
2)иначе время выполнения Process pro меньше 5 минут, надо выводить время выполнения.
спасибо.