Próbuję użyć współbieżności w Haskell dla konkretnej optymalizacji, w której wymagana jest tylko jedna z dwóch wartości, a w zależności od sytuacji jedna z nich może być znacznie szybsza do stworzenia niż druga.Współbieżność Haskella - czy forkIO jest naprawdę niedeterministyczne?
Pomyślałem, że mogę uruchomić 2 wątki z forkIO, a następnie poczekać, aż wartość zostanie umieszczona w MVar. Oto prosty test Pisałem o tym:
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)
skompilowany z:
ghc --make -threaded Test
jednak jedyny przypadek lewicy s kiedykolwiek osiągnięty, chociaż coraz prime powinien wystarczająco długo dla makeInt wątek, aby rozpocząć (i powrót 2 naprawdę nie powinno zająć tyle czasu). Dlaczego tak jest i jak to naprawić?
Jak uruchomić swój kod? Domyślnie haskell używa lekkich wątków zamiast rzeczywistych wątków systemu operacyjnego. Nie znam szczegółów, ale to może zmienić politykę planowania lotów. –
Może to nie pasuje do twojej sprawy, ale możesz również przyjrzeć się, jak wygląda praca nad "spekulatywnym paralelizmem": http://hackage.haskell.org/package/speculation – jberryman
FYI, http://hackage.haskell.org/package/monad-par udostępnia dość przyjemny, zewnętrznie czysty interfejs równoległy API, który jednak pozwala wyraźnie określić rozwidlenia, łączenia itp. –