在Haskell的控制台上同时打印2 o / p

时间:2019-07-12 10:08:41

标签: multithreading haskell io functional-programming multicore

我想在Haskell中同时从控制台上的两个不同功能打印实时输出。

有可能吗?

您可以使用此代码...

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)

我希望a和b在不同的内核上同时计算,并同时在控制台上打印它们的进度。

1 个答案:

答案 0 :(得分:2)

您可以通过使用print生成两个线程来运行两个并发的forkIO操作。每个线程计算并打印自己的输出,然后向主线程发出终止信号。

例如:

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

请注意:

  1. 输出可能同时发生。即使不太可能,输出字符串1425也可能被交错为1245。一个人应该使用另一把锁来防止这种情况。

  2. 两个Haskell线程可以在不同的内核或同一内核上运行。如果计算时间很长,那么我们使用的是线程RTS(使用-threaded进行编译),并且如果我们指定了足够的内核(使用类似./myExe +RTS -N2 -RTS的可执行文件,则仅使用-N将选择所有可用的内核),RTS应该使用多个内核。

在这里,在得到的两个线程中计算fib 38fib 39

$ 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

在第一个测试中,两个Haskell线程在同一OS线程之上运行,大约只使用一个内核。