Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a Haskell thread joined?

As a former C++ programmer, the behaviour of Haskell threads is confusing. Refer to the following Haskell code snippet:

import Control.Concurrent
import Control.Concurrent.MVar
import Data.Functor.Compose
import System.Random

randomTill0 :: MVar () -> IO () -- Roll a die until 0 comes
randomTill0 mV = do
    x <- randomRIO (0,65535) :: IO Int
    if 0 == x
        then putMVar mV ()
        else randomTill0 mV

main :: IO ()
main = do
    n <- getNumCapabilities
    mV <- newEmptyMVar
    sequence (replicate n (forkIO (randomTill0 mV)))
    readMVar mV
    putStrLn "Excution complete."

As far as I know, Haskell's forkIO is roughly equivalent to C++'s std::async. In C++, I store a std::future which is returned by std::async, then std::future::wait for it, then the thread will be std::thread::joined.

(Regarding the tiny delay before the message, I don't think any laziness is involved here.)

My question is:

  1. In the above Haskell code snippet, when are the threads resulting from forkIOs joined? Is it upon readMVar mV, or the end of main?

  2. Is there a Haskell equivalent of std::thread::detach?

like image 415
Dannyu NDos Avatar asked Jan 26 '23 16:01

Dannyu NDos


1 Answers

As far as I understand, threads are never joined, and the program ends when main ends. This is special to main –– in general threads are not associated to each other in any kind of hierarchy. The concept of joining a thread does not exist: a thread runs until its action is finished or until it is explicitly killed with killThread, and then it evaporates (thanks, garbage collector). If you want to wait for a thread to complete you have to do it yourself, probably with an MVar.

It follows that there is no analogue of detach –– all threads are automatically detached.

Another thing worth mentioning is that there is not a 1:1 correspondence between OS threads and Haskell threads. The Haskell runtime system has its own scheduler that can run multiple Haskell threads on a single OS thread; and in general a Haskell thread will bounce around between different OS threads over the course of its lifetime. There is a concept of bound threads which are tied to an OS thread, but really the only reason to use that is if you are interfacing with code in other languages that distinguishes between OS threads.

like image 174
luqui Avatar answered Jan 29 '23 12:01

luqui