2014-02-06 2 views
0

처음 두 개의 다른 시스템에 ssh'es하는 프로그램을 작성하려고하고 있는데, 그런 다음 이들에 대해 일부 HTTP 요청을 실행합니다. 즉, 내 http 요청을 실행할 수 있으려면 ssh 터널이 실행 중이어야합니다.자식 스레드가 시작된 후에 만 ​​주 스레드가 계속 실행되도록하려면 어떻게해야합니까?

Thread thread1 = new Thread(new Runnable(){ 
      public void run(){ 
       try{ 
        Process p1 = Runtime.getRuntime().exec("ssh -A -L12345:localhost:54321 firsthost.com"); 
        p1.waitFor(); 
       }catch (Exception e){} 
      } 
     }) ; 
     thread1.start(); 

    Thread thread2 = new Thread(new Runnable(){ 
     public void run(){ 
      try{ 
       Process p2 = Runtime.getRuntime().exec("ssh -A -L12345:localhost:54321 secondhost.com"); 
       p2.waitFor(); 
      }catch (Exception e){} 
     } 
    }) ; 
    thread2.start(); 

이제 문제는 스레드를 시작한 후, 그렇지 않은 것을 항상 즉시 실행을 시작한다 :

내가 무슨 짓을하는 것은 내가 각 상자 중 하나에 ssh 명령을 실행하는 두 개의 스레드를 가지고있다 , 이는 연결이 이루어지기 전에 제가 요청을 보낼 것을 의미합니다. 스레드가 시작된 후 내 메인 프로그램으로 만 돌아갈 수 있도록 잠금 또는 뮤텍스를 사용하지 않고 간단한 방법이 있습니까? (나는 결코 끝나지 않기 때문에 끝나기를 기다리는 것을 원하지 않는다.) 첫 번째 명령을 한 번 실행하라.이 두 개의 분리 된 쓰레드 대신 백그라운드에서 프로세스를 실행하는 더 좋은 방법이 있다면, 너무 좋을 것이다!)

고마워!

답변

1

-f-N 플래그를 추가하여 포트 전달이 설정되면 ssh에 배경을 알리십시오. 그런 다음 주 스레드에서 ssh 명령을 실행하고 계속하기 전에 종료 할 때까지 기다릴 수 있습니다 (예 : 배경 자체).

-f

요청은 명령을 실행하기 전에 배경에 갈 ssh를. 이는 ssh가 암호 나 암호를 요구할 때 유용하지만 사용자가 백그라운드에서 암호를 원할 때 유용합니다. 이는 -n을 의미합니다. 원격 사이트에서 X11 프로그램을 시작하는 데 권장되는 방법은 ssh -f host xterm입니다.

ExitOnForwardFailure 구성 옵션이 "예"로 설정된 경우 -f으로 시작한 클라이언트는 백그라운드에서 자신을 배치하기 전에 모든 원격 포트 전달이 성공적으로 완료 될 때까지 대기합니다.

-N

원격 명령을 실행하지 마십시오. 이는 전달 포트 (프로토콜 버전 2 전용)에 유용합니다.

직접 이후 JDK5에서 권장되지 않는 모든 사용하여 스레드의

+0

고마워요! 네, -f와 -N은 효과가있었습니다. 이제 패스 프레이즈 입력을 피하는 방법을 알아야합니다. (쉘에서 ssh를 할 때 패스 프레이즈를 어떻게 든 표시하지는 않지만 이런 식으로합니다.) 그러나 이것 이외에는 아주 간단한 해결책이었습니다 :) – N3da

-1

thread1.getState() 메서드를 사용하여 스레드의 상태를 가져올 수 있습니다. thread1.start()를 실행 한 후에는 RUNNABLE 상태로 이동해야합니다. thread1이 프로세스가 완료되기를 기다리고 있으면, 블록 상태가됩니다.

+0

'ssh'가 포트 포워딩을 성공적으로 설정했을 때 알면 도움이되지 않습니다. –

+0

당신이 옳습니다. 나는 그 문제를 오해했다. –

0

먼저 (불행하게도 나는 그 순간. 사과가 작동하지 않는 경우.에서이 테스트를 드릴 수 없습니다). 잘 포장 된 집행자가 우리를 위해 일할 것입니다.당신이 자바의 낮은 버전이 있거나 다음이 방법으로 여전히이 작업을 수행하려면, 여기에서 빠른 해결책,

공용 클래스 홈페이지는 {

public static void main(String... objs) throws Exception { 

    final Process1Thread p1Thread = new Process1Thread(); 
    final Process2Thread p2Thread = new Process2Thread(); 

    Thread p1 = new Thread(p1Thread); 
    Thread p2 = new Thread(p2Thread); 

    p1.start(); p2.start(); 

    while(true) { 
     if(p1Thread.isFinishedCommand() && p2Thread.isFinishedCommand()) { 
      //send commands 
      System.out.println("sending commands"); 
      break; 
     } 
    }  
} 

interface FinishedCommand { 
    boolean isFinishedCommand(); 
} 

static class Process1Thread implements Runnable, FinishedCommand { 

    private boolean finished = false; 

    @Override 
    public boolean isFinishedCommand() { 
     synchronized(this) { 
      return finished; 
     } 
    } 

    @Override 
    public void run() {   
     try { 
      final Process p2 = Runtime.getRuntime().exec("dir"); 

      synchronized(this) { 
       finished = true; 
      }    
      p2.waitFor(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    }  
} 


static class Process2Thread implements Runnable, FinishedCommand { 

    private boolean finished = false; 

    @Override 
    public boolean isFinishedCommand() { 
     synchronized(this) { 
      return finished; 
     } 
    } 

    @Override 
    public void run() {   
     try { 
      final Process p2 = Runtime.getRuntime().exec("dir"); 

      synchronized(this) { 
       finished = true; 
      }    
      p2.waitFor(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

}

감사 Lyju

관련 문제