[英]How to make sure the main thread continues only after child thread has started?
I am trying to write a program that first ssh'es to two different machines, and then executes some http requests against them. 我正在尝试编写一个程序,该程序首先将ssh加载到两台不同的计算机上,然后对它们执行一些http请求。 This means that in order to be able to execute my http requests the ssh tunnel should be running. 这意味着为了能够执行我的http请求,ssh隧道应该正在运行。
What I have done is that I have two threads, each running the ssh command to one of the boxes: 我所做的是,我有两个线程,每个线程都对其中一个框运行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();
Now the problem is that after starting the threads, they do not always immediately start running, which means that I will send my requests before the connection is made. 现在的问题是,启动线程后,它们并不总是立即开始运行,这意味着我将在建立连接之前发送请求。 Is there a simple way (without using locks or mutex) that I can make sure I only return to my main program after the threads are started? 是否有一种简单的方法(不使用锁或互斥锁)可以确保仅在线程启动后才返回主程序? (I don't want of course to wait for them to end because they never end. Just run the first command once :) Also if there is a better way to run the processes in the background instead of having these two seperate threads, that would be great too!) (我当然不想等待它们结束,因为它们永远不会结束。只需运行第一个命令一次即可:)另外,如果有更好的方法在后台运行进程,而不是使用这两个单独的线程,那太好了!)
Thanks! 谢谢!
Try adding the -f
and -N
flags to tell ssh to background itself once the port forwarding is setup. 设置端口转发后,尝试添加-f
和-N
标志以使ssh自身进入后台。 Then you can execute the ssh
commands in the main thread and wait until they exit (ie background themselves) before continuing. 然后,您可以在主线程中执行ssh
命令,并等待它们退出(即,自身退出),然后再继续。
-f
Requests ssh to go to background just before command execution. 请求ssh在执行命令之前进入后台。 This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. 如果ssh要求输入密码或口令,但用户希望在后台输入密码或口令,则此功能很有用。 This implies
-n
. 这意味着-n
。 The recommended way to start X11 programs at a remote site is with something likessh -f host xterm
. 建议在远程站点上启动X11程序的方法是使用ssh -f host xterm
。If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with
-f
will wait for all remote port forwards to be successfully established before placing itself in the background. 如果ExitOnForwardFailure配置选项设置为“ yes”,则以-f
开头的客户端将等待所有远程端口转发成功建立,然后再将其置于后台。
-N
Do not execute a remote command. 不要执行远程命令。 This is useful for just forwarding ports (protocol version 2 only). 这对于仅转发端口(仅协议版本2)很有用。
(Unfortunately I'm unable to test this at the moment. Apologies if it doesn't work.) (不幸的是,目前我无法对此进行测试。如果无法正常使用,我深表歉意。)
First of all using threads directly is not encouraged in JDK5 onwards. 首先,从JDK5开始不建议直接使用线程。 The well packed Executors will do the job for us. 打包的执行者将为我们完成这项工作。 If you have a lower version of java or you want to do this still in this way then, here is one quick solution, 如果您的Java版本较低,或者您仍希望以这种方式进行操作,那么这里有一个快速解决方案,
public class Main { 公共班级主要{
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();
}
}
}
} }
Regards Lyju 问候Lyju
You can use thread1.getState() method to get the state of the thread. 您可以使用thread1.getState()方法获取线程的状态。 After you can thread1.start() it should be moved to RUNNABLE state. 在可以使用thread1.start()之后,应将其移至RUNNABLE状态。 When thread1 is waiting for the process to finish it will be in BLOCKED state. 当thread1等待进程完成时,它将处于BLOCKED状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.