RobotHelper icon indicating copy to clipboard operation
RobotHelper copied to clipboard

关于中断脚本的问题

Open wnight9527 opened this issue 4 years ago • 14 comments

目前main()里 在不停的进行点击,识图操作。 在【停止脚本】按钮加了 thread.interrupt();希望通过捕捉异常的方式停止脚本。 把脚本放在try里面。try{脚本} catch ( InterruptedException e ) {} 但基本停不下来。 我现在是在识图的方法里加了判断,然后exit。但这样直接把整个程序弄崩了。。 if(Thread.currentThread().isInterrupted()){ System.exit( 0 ); }

大佬,有没有什么好点的办法?网上查了资料,好像java里就是不太好停止一个正在运行的程序。只能一步步判断正常结束线程吗?

wnight9527 avatar Dec 23 '20 15:12 wnight9527

目前这个项目的处理逻辑:

点击开始按钮->新开一个线程运行cn.xjiangwei.RobotHelper.GamePackage.Main.start()

但是jdk1.6以后,java移除了thread.stop()函数,导致无法强行停止一个线程。而通过thread.interrupt()给线程发送中断信号需要用户代码自己实现业务逻辑的中断操作,目前我也没有什么好的思路

Jinnrry avatar Dec 24 '20 07:12 Jinnrry

System.exit(0)是退出进程,并不是退出线程。目前你只能通过结束你的业务逻辑来退出线程

Jinnrry avatar Dec 24 '20 07:12 Jinnrry

是的,只是比我在业务逻辑里一个个加退出逻辑方便点。。。

发送自 Windows 10 版邮件https://go.microsoft.com/fwlink/?LinkId=550986应用

发件人: 木木的木头mailto:[email protected] 发送时间: 2020年12月24日 15:07 收件人: Jinnrry/RobotHelpermailto:[email protected] 抄送: whitemailto:[email protected]; Authormailto:[email protected] 主题: Re: [Jinnrry/RobotHelper] 关于中断脚本的问题 (#35)

System.exit(0)是退出进程,并不是退出线程。目前你只能通过结束你的业务逻辑来退出线程

― You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/Jinnrry/RobotHelper/issues/35#issuecomment-750780646, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEYWWTLDZ4EP3WGNM45WNY3SWLSDVANCNFSM4VHEGF4Q.

wnight9527 avatar Dec 24 '20 07:12 wnight9527

https://www.cnblogs.com/greta/p/5624839.html 不知道有没有帮助,毕竟我对这块也不熟悉

chongkaechin avatar Jan 09 '21 15:01 chongkaechin

@chongkaechin 不行的,stop方法在jdk1.8中已经移除了,应该没有任何方法可以强制停止掉一个线程

我有个思路是把业务逻辑代码放到一个新的进程中去运行,停止的时候直接kill掉这个进程。但是由于业务代码和框架代码不在同一个进程,这之间涉及到太多跨进程通信,改动较大。目前在 feature-Runtime分支 已经改成进程实现了。这个分支中停止功能没问题,但是截图功能还没实现跨进程通信。

理论上使用新进程来运行业务逻辑是没问题的,但是跨进程通信需要修改的东西太多,目前还没改完。如果后续有人有这个需求的话可以继续在这个分支上面开发

Jinnrry avatar Jan 12 '21 04:01 Jinnrry

if(Thread.currentThread().isInterrupted()){ return; } 修改结束为返回,即可。

liuhulu avatar Mar 09 '21 08:03 liuhulu

@liuhulu 这样能够实现功能。但是使用Interrupt命令的话需要业务代码适配,如果业务代码不适配的话是没任务意义的。

作为框架的话,更加期望的是点击“停止”按钮就结束脚本运行,并且业务代码不用满篇都是

if(Thread.currentThread().isInterrupted()){
return;
}

举个例子:

就我目前编写脚本的经验来说,对于脚本的业务代码,经常会有类似这样的

while(True) {
   do something.....
}

如有业务代码需要关心中断命令的话,那么代码的每一个while循环里面都需要判断中断,将会导致代码很丑很难看。另外,对于脚本的业务逻辑来说,一般并不需要安全退出,直接结束运行就行了。因此强行退出线程或者进程反而更加优雅,但是由于java8以后移除了线程的stop()方法,所以只有使用进程来实现。但是一个程序引入多进程以后又会导致开发困难,稳定性下降(按键精灵长时间运行会假死,原因就是worker进程挂掉了)

Jinnrry avatar Mar 09 '21 11:03 Jinnrry

最最完美的解决方案我觉得可能需要主进程作为work进程的守护进程,实现类似supervisor的作用,保证work进程稳定,同时work进程和main进程使用网络通讯,并且work进程应该设计成无状态的,保证系统杀死以后重启不需要恢复状态。

but,进程之间需要坐的通信过多过复杂,工作量太大,我目前没这么多的精力去实现

Jinnrry avatar Mar 09 '21 11:03 Jinnrry

刚刚仔细想了下,可行的思路可以把业务代码全部放到新的work进程中运行。目前主进程中所有方法可以使用grpc或者thrift之类的rpc协议将其全部暴露出来。这样对现有代码改动是最小的。

但是这样的话因为业务代码全部在work进程,导致work进程就是有状态的,如果操作系统杀死了work进程,主进程就算重新拉起work,也不能恢复以前的运行状态了。这样就需要业务代码去做相应的维护

Jinnrry avatar Mar 09 '21 11:03 Jinnrry

方案一,简单,粗暴,改动一般。 1,把所有操作绑定在一个对象身上。假设这个对象叫Robot。 2,Main.start中通过Robot.getBitmap/Robot.getTessactOcr/Robot.tap/Robot.xxx...【约定】来进行相关操作。 3,Main.start启动时,注入Robot对象。如,Main.setRobot(Robot).start(); 4,stop时Main.setRobot(null)即可。Main.start中操作Robot出现空指针异常,线程异常结束。

方案二,复杂,优雅,需要设计抽象类、接口和重构。 使用threadlocal绑定线程判定isInterrupted来决定是否执行操作。

liuhulu avatar Mar 09 '21 14:03 liuhulu

@liuhulu 目前就是第二种方案实现的,实现代码在https://github.com/Jinnrry/RobotHelper/blob/master/Android/app/src/main/java/cn/xjiangwei/RobotHelper/Service/RunTime.java

Jinnrry avatar Mar 10 '21 05:03 Jinnrry

@liuhulu 目前就是第二种方案实现的,实现代码在https://github.com/Jinnrry/RobotHelper/blob/master/Android/app/src/main/java/cn/xjiangwei/RobotHelper/Service/RunTime.java

你没理解第二种的概念。这只是堆砌代码。直接继承thread自带这些方法。这个类改进空间非常大。 如果希望简单一些,可以使用future。

liuhulu avatar Mar 11 '21 01:03 liuhulu

@liuhulu 目前就是第二种方案实现的,实现代码在https://github.com/Jinnrry/RobotHelper/blob/master/Android/app/src/main/java/cn/xjiangwei/RobotHelper/Service/RunTime.java

POC代码,没有测试,看下我的提交记录吧。 https://github.com/liuhulu/RobotHelper

liuhulu avatar Mar 11 '21 03:03 liuhulu

@liuhulu 感谢,我周末有空看看,没问题的话我merge进主分支

Jinnrry avatar Mar 11 '21 12:03 Jinnrry