我正在为Clojure编写一个简单的测试数据生成系统,它为给定的函数生成控制流图并对输入数据执行进化搜索。驱动该进化搜索的适应度函数是目标函数的一种形式,在每个条件形式的每个分支处具有标签(例如(if TEST (do (branch-label ...) THEN) (do (branch-label ...) ELSE
)。使用控制流图中节点的索引调用branch-label
函数,该索引对应于函数执行中的当前点和另一个分支的分支距离。然后,该函数基于进场水平和分支距离计算适合度值并将其存储在原子中。为了加快这个过程,我希望健身功能立即终止,如果执行遵循一条路径,这条路径将无法达到目标,或者达到了目标。
我最初的方法是让branch-label
函数抛出一个特定类型的异常然后被我的搜索函数捕获,但后来我发现健身函数本身可能会捕获例如,如果在try-catch块内满足终止条件,则过早地例外。
e.g。假设我们在一个函数中有这个:
(try (if TEST THEN ELSE) (catch Exception _))
健身功能类似于:
(try
(if TEST
(do (branch-label ...) THEN)
(do (branch-label ...) ELSE))
(catch Exception _))
因此,如果branch-label
在哪里抛出任何类型的异常,它将被吞并到这里并且该函数可能会继续运行。
我的另一个想法是在一个单独的线程上运行fitness函数并从分支标签函数内部调用(.stop (Thread/currentThread))
,但似乎所有消息来源都说永远不应该使用Thread.stop。
总而言之,我的问题是试图找到一种(相对)干净的方式,在Clojure的常用控制流机制之外立即逃避正在运行的函数。
答案 0 :(得分:0)
好的,所以我已经达到了我认为是令人满意的解决方案。我没有使用Thread.stop
,而是将健身函数作为未来运行,并将其传递给一个承诺(后者又传递给branch-label
)。主线程然后解除这个承诺(并因此被阻止)。在达到停止条件时,最终适应性将被传递到承诺并且主线程被解锁,并继续取消未来。