【发布时间】:2015-04-29 12:53:06
【问题描述】:
我必须编写一个命令行工具,将一些组件粘合在一起进行实验,并且需要帮助来设计符合我要求的代码。
在顶层,我必须处理每个生成的样本——在运行时以及内存消耗中——使用函数“System.Process.readProcessWithExitCode”对另一个程序进行昂贵的调用。因此,您可以想象有一个(昂贵的)函数“genSample :: IO a”,并且您需要该函数的 n 个返回值。
我的要求是: 1. 假设 p 是处理器的数量,那么最多 p 个样本(即对 genSample 的调用)应该并行计算。 2. 应该可以设置一个超时来中止样本的生成。 3. 如果所有样本的计算都超时,则应该停止在 genSample-call 中启动的进程
我当前的解决方案满足要求 1 和 2。对于第三个解决方案,我目前通过执行 killall-command 来帮助自己。这对我来说似乎是一个肮脏的黑客。也许有人有更好的主意?
这是我当前解决方案的核心部分:
import qualified Control.Monad.Par.Class as ParIO
import qualified Control.Monad.Par.IO as ParIO
…
-- | @parRepeatM i n a@ performs action @a@ @n@ times in parallel with timeout @t@
parRepeatM :: ParIO.NFData a =>
Integer -- ^ timeout in seconds
-> Integer -- ^ number of duplicates (here: number of req. samples)
-> IO a -- ^ action to perform (here: genSample)
-> IO (Maybe [a])
parRepeatM t n a = timeout t $ ParIO.runParIO $ do
let tasks = genericReplicate n $ liftIO a -- :: [ParIO a]
ivars <- mapM ParIO.spawn tasks
mapM ParIO.get ivars
目前的一个核心问题是,在由于超时而中止后,在 genSample 中调用的命令会继续执行——在最坏的情况下,直到整个 haskell-gluing-program 结束。
【问题讨论】:
标签: haskell parallel-processing timeout