【问题标题】:Not able to stop command line process started in thread (in javafx)无法停止在线程中启动的命令行进程(在 javafx 中)
【发布时间】:2017-02-10 06:44:28
【问题描述】:

我已经在一个线程中使用 Java 进程构建器启动了一个命令行 perl 进程。当我关闭我的 javafx 应用程序时,perl.exe 进程继续运行。

我想关闭 cmd 进程的输入流并停止该线程。

我已经尝试过以下步骤:

  1. System.exit
  2. process.getInputStream.close()
  3. 还尝试使用 java cmd 进程 (taskkill /f /im perl.exe) 杀死进程

代码:

MyRunnable 类:

    public  class MyRunnable implements Runnable 
    {
       private final int value;
       private Boolean stop = false;
       MyRunnable(int value) 
         {
            this.value = value;
         }
       @Override
       public void run() 
          {
            try
               {
                  ProcessBuilder pb2 = new ProcessBuilder(new String[] {   "cmd.exe", "/c", "perl E:\\PerlRunner\\SCRIPTS\\AIRPLANE.pl SP9830A510159222101"});
                  Process pr12=pb2.start();
                  Thread.sleep(1000);
                  BufferedReader brq = new BufferedReader(new InputStreamReader(pr12.getInputStream()));
                  while(brq.readLine()!=null && Variables.flag )
                  {
                    System.out.println(brq.readLine()+" FLAG:IN WHILE"+Variables.flag);
                  }
                  if(!Variables.flag)
                  {
                    pr12.destroy();
                    System.out.println("PROCESS DESTOYED:"+Variables.flag);
                  }

               }
               catch(IOException ee)
               {

               }
               catch(InterruptedException rr)
               {    
               }
             }
           }

主要课程:

两个按钮:

播放:

    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            Variables.flag=true;
            System.out.println("Start");
            MyRunnable n1= new MyRunnable(0);
              Thread t1=new Thread(n1);
              t1.start();
        }});

停止按钮:

    btn1.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            Variables.flag=false;
        }});

Variables.flag 是在另一个类中定义的静态变量。

Perl 进程:

    #!/usr/bin/perl
    $devices = $ARGV[0];
    $temp = 0;
    $LOGFILE = "E:\\PerlRunner\\times.txt";
    open(LOGFILE) or die("Could not open log file.");
    foreach $line (<LOGFILE>) {           
    if (index($line, "flmTimes") != -1)
    {
    my $result = index($line, "=");
    $temp = substr($line, $result + 1);
    }
    sleep(1);
    }
    for($i=1; $i<=$temp;$i++)
    {
    system("adb -s $devices shell am start -a
    android.settings.AIRPLANE_MODE_SETTINGS");
    sleep 5;
    system("adb -s $devices shell input tap 200 200");
    sleep 35;
    system("adb -s $devices shell input keyevent KEYCODE_HOME");
    sleep 3;
    }

    times.txt :
    testTimes=1
    flmTimes=3
    mtcTimes=1
    caseTimes=1

【问题讨论】:

  • 任何cmets,我的建议可行吗?
  • 提示:你希望别人花时间帮助你。因此,请您花 5 分钟时间来正确格式化/缩进 all 代码;而不是在这里丢掉这样一个(抱歉)混乱。
  • 我解决了。由于 java 线程启动了另一个进程,因此在调用 destroy 后它不会被杀死。 ProcessBuilder pb3 = new ProcessBuilder(new String[] { "cmd.exe", "/c", "taskkill /im \"perl.exe\" /f"});进程pr13=pb3.start();
  • 很高兴您自己找到了解决方案。当我看到你的 perl 代码时,我怀疑类似的事情,但忘了告诉你。如果您将其写为答案……我不能接受,但会赞成。如果您发现这对您有价值,至少可以让您投票赞成我的回答;-)

标签: java multithreading javafx cmd process


【解决方案1】:

ProcessBuilder start() 方法返回一个 Process 对象。

这有一个 destroy() 方法。就这么叫吧!

【讨论】:

  • 提示:你可以在这里删除所有的 cmets。好的工匠总是把他们的东西整理得井井有条;优秀的程序员或 SO 社区成员也是如此;-)
【解决方案2】:

由于 java 线程启动了另一个进程,所以它不会在调用 destroy 后被杀死。以下命令摆脱了 all perl 进程,从而解决了问题:

ProcessBuilder pb3 = new ProcessBuilder(new String[] { "cmd.exe", "/c", "taskkill /im \"perl.exe\" /f"}); 
Process pr13=pb3.start();

【讨论】:

  • 这里要注意一点:理解这会杀死所有你的 perl 进程。因此,当您在该系统上运行 任何 其他 perl 时,这与您的应用程序无关......也会被杀死!
猜你喜欢
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多