【问题标题】:Printing 2 o/p s at same time on console in Haskell在 Haskell 的控制台上同时打印 2 个 o/p
【发布时间】:2019-11-22 02:17:31
【问题描述】:

我想在 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,并同时在控制台上打印它们的进度。

【问题讨论】:

  • 一个函数一般根本无法打印到控制台。 IO 操作可以,但如果您想要并行 IO,那么您需要查看并发,而不是并行性。

标签: multithreading haskell io functional-programming multicore


【解决方案1】:

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

例如:

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 线程之上,大致只使用一个内核。

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2013-06-15
    • 1970-01-01
    • 2016-11-12
    相关资源
    最近更新 更多