3 ms·
I tried this code with ghc 7.6.3: import Control.Concurrent main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") It only ou
by millstone 12y ago
I tried this code with ghc 7.6.3:
import Control.Concurrent
main = do
forkIO (putStrLn "thing1")
forkIO (putStrLn "thing2")
It only outputs "thing1", not "thing2". What gives?
- wyager 12y agoThe whole process dies before "thing2" gets a chance to do anything. The idea is that if the main thread is done and not waiting, we don't really care about what any of the child threads are doing, so we just axe them.
- millstone 12y agoHmm, ok. I tried adding an infinite loop after the forkIO calls: import Control.Concurrent loop :: Int -> Int loop x = loop x main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") putStrLn $ show (loop 0) Now the program runs forever, but to my surprise doesn't output anything. I think Haskell's concurrency must be very different from the types I'm familiar with.
- dragonwriter 12y agoThe parallelism (or not) of GHC concurrency depends on various options; if you don't link with the "-threaded" option, you are running green threads in a single native thread (N:1 instead of M:N). See: http://www.haskell.org/haskellwiki/Concurrency http://www.haskell.org/haskellwiki/Concurrency and http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/using-smp.html http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/using... And Haskell threads aren't preempted except on memory allocation, so a tight loop without memory allocation never is preempted, so the main thread here never is forced out of control.
- wyager 12y ago>I think Haskell's concurrency must be very different from the types I'm familiar with. It's very different from most concurrency systems. It's a very, very lightweight cooperative green thread system. We're kind of dealing with pathological edge cases here. We're forking to do exceptionally simple, fast things (you shouldn't do that) and we're trying to sleep by wasting CPU cycles (you shouldn't do that). For example, this works fine: import Control.Concurrent main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") threadDelay 1000 threadDelay doesn't hog CPU cycles, so the other threads are able to run.
- millstone 12y agoThank you for the explanation. Your code works for me too.