Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于中断脚本的问题 #35

Open
wnight9527 opened this issue Dec 23, 2020 · 14 comments
Open

关于中断脚本的问题 #35

wnight9527 opened this issue Dec 23, 2020 · 14 comments
Labels
help wanted Extra attention is needed

Comments

@wnight9527
Copy link

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

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

@Jinnrry Jinnrry pinned this issue Dec 24, 2020
@Jinnrry
Copy link
Owner

Jinnrry commented Dec 24, 2020

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

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

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

@Jinnrry Jinnrry added the help wanted Extra attention is needed label Dec 24, 2020
@Jinnrry
Copy link
Owner

Jinnrry commented Dec 24, 2020

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

@wnight9527
Copy link
Author

wnight9527 commented Dec 24, 2020 via email

@chongkaechin
Copy link

chongkaechin commented Jan 9, 2021

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

@Jinnrry
Copy link
Owner

Jinnrry commented Jan 12, 2021

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

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

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

@liuhulu
Copy link

liuhulu commented Mar 9, 2021

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

@Jinnrry
Copy link
Owner

Jinnrry commented Mar 9, 2021

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

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

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

举个例子:

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

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

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

@Jinnrry
Copy link
Owner

Jinnrry commented Mar 9, 2021

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

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

@Jinnrry
Copy link
Owner

Jinnrry commented Mar 9, 2021

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

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

@liuhulu
Copy link

liuhulu commented Mar 9, 2021

方案一,简单,粗暴,改动一般。
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来决定是否执行操作。

@Jinnrry
Copy link
Owner

Jinnrry commented Mar 10, 2021

@liuhulu
Copy link

liuhulu commented Mar 11, 2021

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

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

@liuhulu
Copy link

liuhulu commented Mar 11, 2021

@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

@Jinnrry
Copy link
Owner

Jinnrry commented Mar 11, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants