As GHC documentation says, setting +RTS -N
will use multiple threads to run the program. What if my program is a simple single-threaded program (i.e. no par
, no forkIO
) like the following?
m = 10^6
wr 0 = return ()
wr i = do
appendFile "/tmp/data.nothing" $ show(i)++"\n"
wr (i-1)
main = do
wr m
putStrLn "done"
However, when I run the program with the -Ds
(debugging scheduler) flag, I got following log
all threads:
threads on capability 0:
threads on capability 1:
thread 7 @ 0x7fd5b0199000 is not blocked (TSO_DIRTY)
thread 1944 @ 0x7fd592dc6390 is not blocked (TSO_DIRTY)
thread 1945 @ 0x7fd592def8a8 is not blocked
thread 1946 @ 0x7fd592dc6790 is not blocked
thread 1947 @ 0x7fd592e0f790 is not blocked
thread 1948 @ 0x7fd592df2420 is not blocked
thread 1949 @ 0x7fd592df2000 is not blocked
thread 1950 @ 0x7fd592e0f000 is not blocked
thread 1951 @ 0x7fd592ddae90 is not blocked
thread 1952 @ 0x7fd5b0156cc0 is not blocked
thread 1953 @ 0x7fd5b2a2adc8 is not blocked
thread 1954 @ 0x7fd5b2920568 is not blocked
thread 1955 @ 0x7fd592c4b5a0 is not blocked
thread 1956 @ 0x7fd5b289e7a8 is not blocked (TSO_DIRTY)
thread 1957 @ 0x7fd592c4e160 is not blocked (TSO_DIRTY)
thread 1958 @ 0x7fd592dc54a8 is not blocked (TSO_DIRTY)
I really wonder what all these thousands of threads are doing here?
There is a confusion between GHC threads and OS threads.
"A thread is represented by a TSO (thread-state object) by GHC […] Threads are run by Capabilities, which can be thought of virtual cores managed by GHC. Capabilities are, in turn, mapped to true operating system threads, or Tasks, though we won’t talk about them much."
Inside 206-105 − The GHC scheduler
See also The Glasgow Haskell Compiler − The Scheduler
What you’re actually looking for are capabilities. If you run your program with
+RTS -N1
you will see that there is only one capability, 2 for+RTS -N2
etc.You may also note that even though your program is single threaded by nature, the runtime system can use different threads for other tasks like the garbage collector.