Haskell的制片人和消费者问题?

时间:2009-08-12 19:46:26

标签: multithreading haskell concurrency functional-programming

我想如何在像Haskell这样的函数式编程语言中实现生产者/消费者?以及它与命令式语言有何不同?我对函数式编程语言的理解是原始的。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:14)

使用抢先线程和通过频道传递的消息的生产者/消费者抽象:

import Data.Char
import Control.Concurrent
import Control.Concurrent.Chan

main = do
    c  <- newChan
    cs <- getChanContents c     -- a lazy stream of events from eventReader
    forkIO (producer c)          -- char producer
    consumer cs

  where
    -- thread one: the event producer
    producer c = forever $ do
        key <- getChar
        writeChan c key

    -- thread two: the lazy consumer
    consumer = mapM_ print . map shift
        where shift c | isAlpha c = chr (ord c + 1)
                           | otherwise = c

你会在Erlang中使用类似的模型。代表消费者和生产者的线程,以及它们之间的共享消息管道,每个消息都是异步的。

答案 1 :(得分:6)

我将添加dons的优秀答案,这里的基础机制称为MVar,它是一个值必需的并行容器。你“放”和“进入”进入和离开一个MVar。获得一个空的MVar块,就像放一个完整的一样。它同时是一种通信机制和同步机制。我认为它是由Arvind发明的Monsoon / * t项目的一部分。有一个美丽的book by Nikhil and Arvind解释了他们的并行Haskell的pH方言。许多想法已经被GHC采纳,这本书非常值得一读。

答案 2 :(得分:2)

除了Norman和Don提到的有状态方法之外,您还可以将正常的功能应用和懒惰视为生产者和消费者。

以下是自然数字的制作人:

nats = [1..]

这是一个计算这些数字的平方的消费者:

squares = map (\x -> x * x) nats

C#中的yield return或Python中的生成器等生产者通常可以这样表达:作为Haskell中的简单惰性列表。