Sto tentando di utilizzare la concorrenza in Haskell per un'ottimizzazione specifica in cui è richiesto solo uno dei due valori e, a seconda della situazione, uno può essere molto più veloce da creare rispetto all'altro.Concorrenza di Haskell - forkIO è davvero non deterministico?
Ho pensato di poter eseguire solo 2 thread con forkIO e quindi attendere che un valore venga inserito in un MVar. Ecco un semplice test che ho scritto per questo:
import Control.Concurrent
main = do out <- newEmptyMVar
t1 <- forkIO (makeString out)
t2 <- forkIO (makeInt out)
v <- takeMVar out
killThread t1
killThread t2
case v of
Left s -> putStrLn s
Right i -> putStrLn $ show i
makeString out = do s <- return (show (primes !! 10000))
putMVar out $ Left s
makeInt out = do i <- return 2
putMVar out $ Right i
primes = sieve [2..]
where sieve (x:xs) = x : (sieve $ filter ((/=0).(flip mod x)) xs)
Compilato con:
ghc --make -threaded Test
Tuttavia, unico caso la sinistra s è mai raggiunto, anche se sempre il primo dovrebbe prendere abbastanza a lungo per la MAKEINT thread per iniziare (e restituire 2 in realtà non dovrebbe richiedere molto tempo). Perché è così, e come posso risolvere questo?
Come si esegue il codice? Per impostazione predefinita haskell utilizza thread leggeri anziché veri thread del sistema operativo. Non conosco i dettagli, ma questo potrebbe cambiare molte politiche di pianificazione. –
Potrebbe non adattarsi al tuo caso, ma potresti anche esaminare alcuni dei lavori sul "parallelismo speculativo" in corso: http://hackage.haskell.org/package/speculation – jberryman
FYI, http://hackage.haskell.org/package/monad-par espone un'API di parallelismo piuttosto piacevole, esternamente pura che tuttavia ti consente di dichiarare in modo esplicito fork, join, ecc. –