在哈斯克尔实施渠道 - 解决尴尬的小队

时间:2015-01-08 22:05:33

标签: haskell concurrency

在论文Tackling the awkward squad中,Simon Peyton Jones提供了Channel的“可能实现”。

type Channel a = (MVar (Stream a) , -- Read end
                  MVar (Stream a) ) -- Write end (the hole)

type Stream a = MVar (Item a)

data Item a = MkItem a (Stream a)

现在,他实现了一个像这样的函数putChan :: Channel a -> a -> IO ()

putChan (read, write) val
  = do { new_hole <- newEmptyVar ;
         old_hole <- takeMVar write ;
         putMVar write new_hole ;
         putMVar old_hole (MkItem val new_hole) }

上面的函数将一个MVar从写入中取出,然后将一个空的MVar放入其中 然后它写入从write中提取的old_hole。

问题是,为什么要写入old_hole?它已从写入中取出,其范围仅限于当前块,那么它有什么区别?

1 个答案:

答案 0 :(得分:4)

  

问题是,为什么要写入old_hole?它已从写入中取出,其范围仅限于当前块,那么它有什么区别?

不完全。 old_hole在&#34;范围内&#34;在阅读方。你需要查看newChan的全貌:

newChan = do { 
    read <- newEmptyMVar ;
    write <- newEmptyMVar ;
    hole <- newEmptyMVar ;
    putMVar read hole ;
    putMVar write hole ;
    return (read,write) }

在致电newChan&#34; old_hole&#34;之后来自putChan的{​​{1}}与MVar中的hole相同。随着渠道运营的进展,newChan总是嵌套在old_hole的{​​{1}}中。

我发现链接列表式频道的设计一开始真的难以理解。该论文的插图在展示结构方面做得不错,但基本的想法是读者&#34;剥离&#34;一层MVar来揭示一个价值,而作家则在底部插入价值&#34;&#34;在一堆MVars中,主要指向最底部的一个。

顺便说一下,这是Control.Concurrent.Chan

中使用的设计