У меня есть следующий фрагмент кода:
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
Я компилирую код и запускаю его следующим образом:
$ 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
<...>
То есть программа приостанавливается при чтении файла. Я нахожу это сбивающим с толку, потому что, если я заменю readFile
на threadDelay
, он корректно выполнит управление.
Что здесь происходит? Разве GHC не сопоставляет код forkIO
'd с другим системным потоком?
(Я использую Mac OS X 10.8.5, но люди сообщают о том же поведении на Ubuntu и Debian)