在Haskell的并行和并发编程中,Simon Marlow提供了Stream a基于以下数据,以及一些生产者和消费者:
data IList a
= Nil
| Cons a (IVar (IList a))
type Stream a = IVar (IList a)
streamFromList :: NFData a => [a] -> Par (Stream a)
streamFromList xs = do
var <- new
fork $ loop xs var
return var
where
loop [] var = put var Nil
loop (x:xs) var = do
tail <- new
put var (Cons x tail)
loop xs tail
Run Code Online (Sandbox Code Playgroud)
后来,他提到了这种方法的缺点并提出了一个解决方案:
在我们之前的例子中,消费者比生产者更快.相反,如果生产者比消费者更快,那么就没有什么可以阻止生产者在消费者面前走很长的路并在内存中建立一个长的IList链.这是不可取的,因为大型堆数据结构由于垃圾收集而产生开销,因此我们可能希望对生产者进行速率限制以避免它过早地进行.有一个技巧可以为流API添加一些自动速率限制.它需要在
IList类型中添加另一个构造函数:Run Code Online (Sandbox Code Playgroud)data IList a = …