我有一个Java程序,它与实现SMT-LIB标准的SMT求解器通信。我的程序使用ProcessBuilder
以交互模式启动SMT求解器作为子进程。然后,它通过子进程的标准输入流(通过Process.getOutputStream()
访问)向求解器发送命令,并通过子进程的标准输出流(通过Process.getInputStream()
访问)读取结果。
由于解决NP难问题可能需要一段时间,我的程序通常会在等待SMT求解器返回结果的read()
调用中花费大量时间。
我目前正在为我的程序制作GUI。 GUI在后台线程上与SMT解算器进行交互,以便在求解器运行时不阻塞前台GUI线程。
我希望用户能够在中途取消操作,终止SMT求解器过程并使用已生成的任何部分结果完成后台操作。
到目前为止我考虑的选项:
我的第一个想法是使用GUI线程中的Thread.interrupt()
来中断后台线程上的阻塞I / O,让后台线程在阻塞{{{ 1}}在完成任务之前使用read()
调用并终止子进程。问题是,据我所知,在进程I / O上被阻塞的线程上调用Process.destroy()
不会中断该块!我希望它会抛出InterruptedIOException或像Thread.interrupt()
包中的可中断I / O一样工作,但它似乎没有。
我的下一个想法是让GUI检查子进程是否通过同步变量运行,如果是,则从GUI线程中终止进程。我认为这会导致后台线程上的java.nio
调用就好像已经达到输入结束一样。这在设计方面非常难看,因为我已经在其他操作中使用read()
向后台线程传达取消请求,我不明白为什么我需要一个特殊情况。用于进程阻止的GUI逻辑与其他类型的阻塞。
我唯一能想到的另一个选择是拥有一个第二个后台线程来处理与子进程的通信,并且只是从/向主背景中继通信线。当GUI在主后台线程上调用Thread.interrupt()
时,主后台线程跳出其监视器阻塞在第二个后台线程上,杀死第二个后台线程阻塞的进程,然后正常进行。但这似乎比它需要的更复杂。
问题
异步中断使用进程在I / O上阻塞的线程的首选方法是什么?
如果重要,我在Windows 7上运行Java 1.8.0u60。