How to force main thread to wait for all its child threads finish in Haskell

前端 未结 1 1456
南方客
南方客 2021-02-08 12:44

In the following Haskell code, how to force main thread to wait till all its child threads finish.

I could not able to use forkFinally as given in the section \"Termina

相关标签:
1条回答
  • 2021-02-08 13:24

    What I did in the past was to create a little MVar for each forked thread and then use forkFinally to fork the threads such that at the very end, each thread would put a dummy value into the MVar (i.e. I used the MVar as a synchronisation primitive). I could then call takeMVar on those MVars to wait.

    I wrapped it into a little helper function:

    forkThread :: IO () -> IO (MVar ())
    forkThread proc = do
        handle <- newEmptyMVar
        _ <- forkFinally proc (\_ -> putMVar handle ())
        return handle
    

    Using this, your code could be changed to something like

    -- Fork four threads
    threads <- forM [5, 3, 7, 1] (\v -> forkThread (transTest n v))
    
    -- Wait for all of them
    mapM_ takeMVar threads
    

    However, that was before I read the (most excellent) book "Parallel and Concurrent Programming in Haskell" by Simon Marlow, which made me aware of the async package. The package provides an abstraction which not only takes care of all these things, so you can write just

    -- Runs 'transTest n {5,3,7,1}' in parallel and waits for all threads
    _ <- mapConcurrently (transTest n) [5, 3, 7, 1]
    

    ...it also takes care of things such as (asynchronous) exceptions.

    0 讨论(0)
提交回复
热议问题