Einar Karttunen wrote:
Hello
Using system or any variant of it from System.Process
seems broken in multithreaded environments. This
example will fail with and without -threaded.
When run the program will print "hello: start" and
then freeze. After pressing enter (the first getChar)
System.Cmd.system will complete, but without that
it will freeze for all eternity.
What is the best way to fix this? I could use System.Posix,
but that would lose windows portablity which is needed.
import Control.Concurrent
import System.Cmd
main = do forkIO (threadDelay 100000 >> hello)
getChar
getChar
hello = do putStrLn "hello: start"
system "echo hello world!"
putStrLn "hello: done"
The reason for the deadlock is because getChar is holding a lock on
stdin, and System.Cmd.system needs to access the stdin Handle in order
to know which file descriptor to dup as stdin in the child process (the
stdin Handle isn't always FD 0, because of hDuplicateTo).
Maybe getChar shouldn't hold the lock while it is waiting. I was
vaguely aware of this when I wrote System.IO, but couldn't see an easy
way to implement it, so currently all operations that block in I/O hold
the Handle lock while they block. Mostly this isn't a problem, but it
does mean that things like hClose will block if there's another thread
blocked in hGetChar on the same Handle (maybe you want it to cause the
hGetChar to immediately fail instead).
One way to work around it in this case is to hDuplicate the standard
Handles, and call runProcess passing your duplicate Handles. I've just
checked; this works fine.
import GHC.Handle (hDuplicate)
main = do
i <- hDuplicate stdin
o <- hDuplicate stdout
e <- hDuplicate stderr
forkIO (threadDelay 100000 >> hello i o e)
getChar
getChar
hello i o e = do
putStrLn "hello: start"
p <- runProcess "echo" ["hello world!"] Nothing Nothing (Just i)
(Just o) (Just e)
waitForProcess p
putStrLn "hello: done"
Cheers,
Simon
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe