我想如何在像Haskell这样的函数式编程语言中实现生产者/消费者?以及它与命令式语言有何不同?我对函数式编程语言的理解是原始的。任何帮助将不胜感激。
答案 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中的简单惰性列表。