Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Data.ByteString.readFile block all threads?

Tags:

I have the following piece of code:

module Main where
import Data.IORef
import qualified Data.ByteString as S
import Control.Monad
import Control.Concurrent

main :: IO ()
main = do
    var <- newIORef False
    forkIO $ forever $ do
        status <- readIORef var
        if status
            then putStrLn "main: file was read"
            else putStrLn "main: file not yet read"
        threadDelay 10000
    threadDelay 200000
    putStrLn ">>! going to read file"
    --threadDelay 200000    --
    str <- S.readFile "large2"
    putStrLn ">>! finished reading file"
    writeIORef var True
    threadDelay 200000  

I compile the code and run it like this:

$ ghc -threaded --make test.hs
$ dd if=/dev/urandom of=large bs=800000 count=1024
$ ./test +RTS -N3
<...>
main: file not yet read
main: file not yet read
main: file not yet read
main: file not yet read
>>! going to read file
>>! finished reading file
main: file was read
main: file was read
main: file was read
main: file was read
<...>

That is, the program pauses when reading a file. I find this confusing because if I replace readFile with threadDelay it yield control correctly.

What is going on in here? Isn't GHC mapping forkIO'd code to a different system thread?

(I am using Mac OS X 10.8.5, but people has reported the same behavior on Ubuntu and Debian)