简体   繁体   English

Haskell:线程和IO类型

[英]Haskell: Thread and IO type

I am studying the Haskell to the thread part. 我正在研究Haskell的线程部分。 I try to create 2 threads to do the different calculation. 我尝试创建2个线程来执行不同的计算。 This is a really simple function just for practice. 这是一个非常简单的功能,仅供练习使用。 The code like this: 像这样的代码:

import Control.Concurrent (forkIO)

task4 a b = do
    forkIO $ a^b
    forkIO $ b^a


    if (a^b) > (b^a) then putStrLn ([a] ++ "^"++[b] ++ "=" ++ [a^b] ++ "is bigger!")
                    else putStrLn ([b] ++ "^"++[a] ++ "=" ++ [b^a] ++ "is bigger!") 

I don't know how to dual with the type inside the do block. 我不知道如何与do块中的类型对偶。 And am I right to create threads like this? 我是否应该创建这样的线程?

Since some time has passed, here's how you would do it with threads: 既然已经过去了一段时间,那么使用线程的方法如下:

-- helper function for all other methods
message a b = (show a) ++ " ? " ++ (show b) ++ " " ++ (show . compare a $ b)

threads a b = do
  abVar <- newEmptyMVar
  baVar <- newEmptyMVar
  forkIO $ putMVar abVar (a^b)
  forkIO $ putMVar baVar (b^a)
  ab <- takeMVar abVar
  ba <- takeMVar baVar
  putStrLn $ message ab ba

That's a mouthful. 满嘴 Even worse, it's not pure anymore. 更糟糕的是,它不再是纯粹的。 After all, your program is basically nothing more than 毕竟,您的程序基本上不过是

simple a b = message (a^b) (b^a)

-- IO version
simpleIO :: Integer -> Integer -> IO ()
simpleIO a b = putStrLn $ simple a b

Or at least it should behave the same. 或者至少它应该表现相同。 If you want to do this in parallel, there's no need for IO , using par and pseq : 如果要并行执行此操作,则无需使用parpseq进行IO

parAB a b = force ab `par` force ba `pseq` message ab ba
  where ab = a^b
        ba = b^a

-- IO version    
parABIO a b = putStrLn $ parAB a b

But in the end, using parallel or concurrent techniques on such simple tasks as a^b won't gain you anything: 但是最后,在诸如a^b这样的简单任务上使用并行或并发技术不会为您带来任何好处:

par is generally used when the value of a is likely to be required later, but not immediately. 通常在可能稍后但不是立即需要a的值时使用par Also it is a good idea to ensure that a is not a trivial computation, otherwise the cost of spawning it in parallel overshadows the benefits obtained by running it in parallel. 同样,确保a不是一个微不足道的计算也是个好主意,否则,并行生成它的成本将使并行运行所获得的收益蒙上阴影。

This can be checked by using Criterion: 可以使用Criterion进行检查:

import Control.Concurrent
import Control.Parallel
import Control.DeepSeq
import Criterion.Main

message a b = (show a) ++ " ? " ++ (show b) ++ " " ++ (show . compare a $ b)

simple, parAB :: Integer -> Integer -> String
simpleIO, parABIO, threads :: Integer -> Integer -> IO ()

simple a b = message (a^b) (b^a)

simpleIO a b = putStrLn $ simple a b

parAB a b = force ab `par` force ba `pseq` message ab ba
  where ab = a^b
        ba = b^a

parABIO a b = putStrLn $ parAB a b 

threads a b = do
  abVar <- newEmptyMVar
  baVar <- newEmptyMVar
  forkIO $ putMVar abVar (a^b)
  forkIO $ putMVar baVar (b^a)
  ab <- takeMVar abVar
  ba <- takeMVar baVar
  putStrLn $ message ab ba

main = defaultMain [
  bgroup "simpleIO" 
    [ bench "1531235 123152123" $ whnf (simpleIO 1531235) 123152123
    , bench "2 121351356" $ whnf (simpleIO 2) 121351356
    , bench "12346 415" $ whnf (simpleIO 12346) 415
    ],
  bgroup "parABIO" 
    [ bench "1531235 123152123" $ whnf (parABIO 1531235) 123152123
    , bench "2 121351356" $ whnf (parABIO 2) 121351356
    , bench "12346 415" $ whnf (parABIO 12346) 415
    ],
  bgroup "threads" 
    [ bench "1531235 123152123" $ whnf (threads 1531235) 123152123
    , bench "2 121351356" $ whnf (threads 2) 121351356
    , bench "12346 415" $ whnf (threads 12346) 415
    ]
  ]

Further resources 更多资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM