Reputation: 151
I want to print real-time output from two different functions on the console at the same time, in Haskell.
Is it possible?
You can use this code...
import Control.Parallel
main = a `par` b `par` c `pseq` print (a + b + c)
where
a = ack 3 10
b = fac 42
c = fib 34
fac 0 = 1
fac n = n * fac (n-1)
ack 0 n = n+1
ack m 0 = ack (m-1) 1
ack m n = ack (m-1) (ack m (n-1))
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
I expect that a and b are calculated simultaneously on different cores and print their progress on the console at the same time.
Upvotes: 1
Views: 305
Reputation: 116139
You can run two concurrent print
actions by spawning two threads with forkIO
. Each thread computes and prints its own output, and then signals the main thread to terminate.
For example:
main :: IO ()
main = do
v1 <- newEmptyMVar
v2 <- newEmptyMVar
forkIO $ do
print (10+4)
putMVar v1 ()
forkIO $ do
print (20+5)
putMVar v2 ()
-- wait for the threads
takeMVar v1
takeMVar v2
Note that:
The outputs might happen at the same time. Even if it's unlikely, it could be possible that the output strings 14
and 25
get interleaved as 1245
. One should use another lock to prevent that.
The two Haskell threads may run on different cores or on the same core. If the computation is long, if we are using the threaded RTS (compile with -threaded
), and if we have specified enough cores (run the executable with something like ./myExe +RTS -N2 -RTS
, using -N
alone will choose all available cores), the RTS should use multiple cores.
Here, computing fib 38
and fib 39
in the two threads I get:
$ time ./ParallelExample ; time ./ParallelExample +RTS -N2 -RTS
39088169
63245986
real 0m9.094s
user 0m9.076s
sys 0m0.020s
39088169
63245986
real 0m5.823s
user 0m9.532s
sys 0m0.040s
In the first test, the two Haskell threads run on top of the same OS thread, roughly using only one core.
Upvotes: 1