我最近遇到了一个案例,可以很方便地产生一堆线程,阻塞并等待一个答案(第一个到达),取消其余线程然后解除阻塞。
例如,假设我有一个采用种子值的搜索函数。让我们规定搜索功能可以简单地并行化。此外,我们的搜索空间包含许多潜在的解决方案,并且对于某些种子值,该函数将无限期地搜索,但至少一个种子值将在合理的时间内产生一个解决方案。
如果我可以完全天真地并行进行此搜索,那就太好了,例如:
let seeds = [|0..100|]
Array.Parallel.map(fun seed -> Search(seed)) seeds
可悲的是,Array.Parallel.map
将阻塞直到所有线程都完成。真可惜。我总是可以在搜索功能中设置一个超时,但我几乎可以肯定要等待运行时间最长的线程完成;此外,对于某些问题,超时可能不够长。
简而言之,我想要类似于 UNIX 套接字select()
调用的东西,仅适用于任意函数。这可能吗?它不必像上面那样采用漂亮的数据并行抽象,也不必是 F# 代码。我什至很乐意使用本机库并通过 P/Invoke 调用它。