假设我有一个函数f
,它接受一个整数参数。 f
可能不会因某些参数而终止,但其结果同样有值(value)。 (具体来说,参数可以是随机数生成器的种子,它被传递给 SAT 求解器。)
我想使用并发并调用 f 1
、f 2
、f 3
等,并在第一个完成时返回。因此,每个线程都应该运行如下所示的代码
comp <- start_proc (f 1)
wait(comp || anyDone) -- wait for _either_ of these signals to be true
if comp then
set anyDone = True
最简单的方法是什么?我想到了 AMB 运算符,但我需要同时运行所有进程(例如在 24 或 80 核机器上)。 (分布式计算解决方案会更好。)粗略地看一下 AMB wiki page表明它可能不支持非终止进程?
测试
目前,我还没有得到我想要的答案。我认为这可能更多是我如何创建流程的问题,而不是其他问题。
定义
runProc (x:xs) =
createProcess (proc x xs) >>= \(_, _, _, h) -> waitForProcess h
然后,我想对 runProc ["zsh", "-c", "sleep 3"]
和 runProc ["ls"]
进行竞赛。我稍微修改了托马斯的答案,但没有成功。
raceL :: [IO α] -> IO α
raceL ops = do
mv <- newEmptyMVar
tids <- forM ops (\op -> forkIO (op >>= putMVar mv))
answer <- takeMVar mv
mapM_ killThread tids
return answer
使用-threaded
编译并使用+RTS -N
运行(我有一台4核机器)似乎没有帮助。
最佳答案
为什么不只是一个 MVar
和 forkIO
?
import Control.Concurrent
import Control.Concurrent.MVar
import System.Environment
import Control.Monad
main = do
mv <- newEmptyMVar
[nrThreads] <- liftM (map read) getArgs
tids <- replicateM nrThreads (forkIO $ operation mv)
answer <- takeMVar mv
mapM_ killThread tids
operation :: MVar Int -> IO ()
operation mv = putMVar mv 5
这将 fork nrThreads
个轻量级线程。一旦一个线程完成,它应该将答案放入提供的 MVar 中。然后所有其他线程将被主线程杀死。不需要显式轮询,因为一旦 MVar
变为非空,GHC RTS 将重新安排 main
。
关于haskell - 在 Haskell 中编写类似信号量的代码的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7216149/