Skip to content

Race condition when multiple threads wait for a process

Consider the following code:

import System.Process
import Control.Concurrent.Async

main :: IO ()
main = do
    (_, _, _, ph) <- createProcess $ shell "sleep 1"
    let helper i = do
            ec <- waitForProcess ph
            print (i :: Int, ec)
    ((), ()) <- concurrently (helper 1) (helper 2)
    return ()

If I compile with the single threaded runtime, I get the output

(2,ExitSuccess)
(1,ExitSuccess)

But when compiling with the multithreaded runtime, I get:

bin: waitForProcess: does not exist (No child processes)

If you need to wait for a process from multiple threads, you can do so now by having a dedicated wait thread which writes to an MVar or TMVar, but the current default behavior can be surprising.

I discussed this in a blog post, and there was some conversation on Reddit.

At the least, I think we need better documentation, but if there's a better solution, that would be best.

Trac metadata
Trac field Value
Version 7.8.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/process
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information