基本线程,交错线程混淆?

时间:2017-03-02 09:29:58

标签: multithreading haskell

我对this指南中给出的交错函数感到有些困惑。

我有以下数据类型:

data M m r = Atomic (m (M m r)) | Done r

我创建了一个提升函数来获取m a,在a内插入Done,然后将Done a重新插入m () 。这形成了Atomic结构:

atm :: Monad m => m a -> M m a
atm m = Atomic $ liftM Done m

我已将M m作为Monad类的实例(基于数据构造函数匹配模式):

instance (Monad m) => Monad (M m) where
   return = Done
   (Atomic m) >>= f = Atomic liftM (>>= f) m
   (Done r) >>= f = f v

有一个简单的实现函数可以访问Atomic wrapper

中的嵌套值
runThread :: Monad m => M m a -> m a
runThread (Atomic m) = m >>= runThread --Extract m and recursively pass to runThread
runThread (Done r) = return r --Return Done

然后,有以下交错函数:

interleave :: Monad m => M m r -> M m r -> M m r
interleave (Atomic m1) (Atomic m2) = do
   next1 <- atm m1 --? 
   next2 <- atm m2 --? 
interleave next1 next2
interleave (Done _) t2 = interleave t2
interleave t1 (Done _) = interleave t1

我的疑惑点在next1 <- atm m1next2 <- atm m2

据我了解,所有这一切都是从m1包装器中取出(Atomic m1)并将其重新插入Atomic包装器中?这个操作如何交错?

我错过了一些基本的东西吗?代码工作正常,所以我确定这是由于我的困惑。

其余代码:

threadOne :: M IO ()
threadOne = do 
  atm $ print 1

threadTwo :: M IO ()
threadTwo = do
  atm $ print 2

main = do
  runThread (interleave threadOne threadTwo)

1 个答案:

答案 0 :(得分:2)

你是部分正确的。代码

next1 <- atm m1

接受第一个线程开始的原子操作,并将其插入到合并/交错的线程中。从atm调用返回的是第一个帖子的继续next1

但接下来,我们正在采取第二个主题的行动,说

next2 <- atm m2

因此合并后的线程最终会从第一个线程执行一个动作,然后从第二个线程执行一个动作。因此“交错”。然后我们继续通过

递归地调用interleave两个延续
interleave next1 next2