2016-01-12 1 views
0

Я использую Java Executors.newWorkStealingPool(); для одновременного запуска нескольких команд. Поскольку ожидается, что некоторые из этих задач будут работать с таймаутом, я добавил для них 2-секундный тайм-аут.Процессы не заканчиваются

ProcessBuilder pb = new ProcessBuilder(cmd.split(" ")); 
Process p = null; 
StringBuilder result = new StringBuilder(); 
try { 
    p = pb.start(); 
    p.waitFor(2000, TimeUnit.MILLISECONDS); 
    BufferedReader errreader = 
    new BufferedReader(new InputStreamReader(p.getErrorStream())); 
    BufferedReader outreader = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    String line = "";   
    while ((line = outreader.readLine())!= null) 
    result.append(line + "\n"); 
    while ((line = errreader.readLine())!= null) 
     result.append(line + "\n"); 
    outreader.close(); 
    errreader.close(); 
    } catch (InterruptedException e) { 
     result.append("INTERRUPTED"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
    } 
    finally { 
     p.destroy(); 
    } 
    .... 
    return b; // b is boolean 

Отправка задачи выглядит следующим образом

List<ImmutablePair> curJobs = new ArrayList<ImmutablePair>(); 
for (int i = 0; i < allMutants.size(); i++) { 
    String mutant = allMutants.get(i); 
    t = executor.submit(new mutTask(mutant)); 
    ImmutablePair pair = new ImmutablePair(mutant, t); 
    curJobs.add(pair); 
    } 

и, наконец. Я собираю результаты в следующем цикле.

// data collection loop 
for (int i = 0; i< curJobs.size(); i++) { 
     ImmutablePair p = curJobs.get(i); 
     String m= (String) p.getLeft(); 
    System.out.println(m); 
     t = (Future<Boolean>) p.getRight(); 
    try { 
     boolean res; 
     try { 
      res = t.get(2000L, TimeUnit.MILLISECONDS); 

     } catch (TimeoutException e) { 
      res = true; 
     } 
     finally { 
      t.cancel(true); 
     }} 

Проблема заключается в том, что тайм-аут не кажется, прекратить некоторые из команд или процессов, как это определено в программе. Через несколько минут циклы сбора данных становятся очень медленными. Результат ps показывает некоторые задания, которые работают намного выше указанного таймаута и сохраняют занятость процессора. Моя конфигурация - JDK8 на CentOS.

+1

Итак, из JavaDocs, мы знаем * "Вызывает текущий поток ждать, если это необходимо, пока подпроцесс, представленное этим объектом процесса не прекращается, или указанное время ожидания истекает. "*, что означает, что этот метод вернется либо в том случае, когда процесс существует, либо через указанное время истекает, так что это означает, что процесс все еще может работать. Затем вы читаете содержимое выходного процесса, что означает, что если процесс все еще разрушается, он либо все еще обрабатывает выходные данные, либо блокирует ... Как правило, я использую дочерний 'Thread' для чтения ввода, когда' waitFor 'возвращает, останавливает эти потоки – MadProgrammer

+0

... а затем уничтожает процесс – MadProgrammer

+0

Спасибо. Как вы заметили, проблема не в проверке вывода 'p.waitFor (2000, TimeUnit.MILLISECONDS);'. – Amin

ответ

0

Как @MadProgrammer отметил, что проблема заключается в чтении/буфере ошибок в случае, если процессы завершаются. Для того, чтобы решить, что вам необходимо проверить вывод p.waitFor(2000, TimeUnit.MILLISECONDS);

try { 
     p = pb.start(); 
     boolean timeout = !p.waitFor(2000, TimeUnit.MILLISECONDS); 
     if (!timeout){ 
      BufferedReader errreader = 
        new BufferedReader(new InputStreamReader(p.getErrorStream())); 
      BufferedReader outreader = 
        new BufferedReader(new InputStreamReader(p.getInputStream())); 

      String line = ""; 
      while ((line = outreader.readLine())!= null) 
       result.append(line + "\n"); 
      while ((line = errreader.readLine())!= null) 
        result.append(line + "\n"); 
      outreader.close(); 
      errreader.close(); 
     } 

    } catch ... 
Смежные вопросы