Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
帮助理解Haskell中的MVar示例_Haskell_Concurrency - Fatal编程技术网

帮助理解Haskell中的MVar示例

帮助理解Haskell中的MVar示例,haskell,concurrency,Haskell,Concurrency,我正在试图理解中的MVar示例- data SkipChan a=SkipChan(MVar(a,[MVar()]))(MVar()) newSkipChan::IO(SkipChan a) newSkipChan=do sem IO() putSkipChan(SkipChan干管)v=do (u,sems)putMVar sem())sems getSkipChan::SkipChan a->IO a getSkipChan(SkipChan主扫描电镜)=do takeMVar扫描电镜 (五

我正在试图理解中的MVar示例-

data SkipChan a=SkipChan(MVar(a,[MVar()]))(MVar())
newSkipChan::IO(SkipChan a)
newSkipChan=do
sem IO()
putSkipChan(SkipChan干管)v=do
(u,sems)putMVar sem())sems
getSkipChan::SkipChan a->IO a
getSkipChan(SkipChan主扫描电镜)=do
takeMVar扫描电镜
(五、中小型企业)IO(SkipChan a)
dupSkipChan(SkipChan main)=do
扫描电镜
  • 您是正确的,另一个线程可能会调用
    putMVar main
    并将
    putSkipChan
    搞砸。但是创建上述代码的模块不会导出
    SkipChan
    构造函数,因此这样的恶意操作是不可能的

  • dupSkipChan
    创建一个名为
    sem
    的新
    emptyMVar
    ,并将其添加到main中的列表中。它不会添加在
    newSkipChan
    中创建的现有文件。因此,没有障碍

  • 向其他读者进一步解释这个问题和评论:这个想法是可能有多个读者线程。最初,SkipChan main sem1是唯一一个这样的读卡器
    dupSkipChan
    生成一个
    SkipChan主sem2
    。如果有数千个读卡器,那么您不希望在
    putSkipChan
    中通知所有读卡器的新值,因此设计是
    getSkipChan
    将其sem放入main中的列表中。在
    newSkipChan
    dupSkipChan
    中初始化
    SkipChan
    还包括将新的空
    sem
    放入main中的列表

    上述初始化和设计意味着第一个
    getSkipChan
    获取最近写入的过去值(或第一个值到达的块)。该
    SkipChan
    上的未来
    getSkipChan
    将始终获得比以前获得的任何值都新的值,并且如果该值已经可用,这些值将不会被阻止

    data SkipChan a = SkipChan (MVar (a, [MVar ()])) (MVar ())
    
    newSkipChan :: IO (SkipChan a)
    newSkipChan = do
         sem <- newEmptyMVar
         main <- newMVar (undefined, [sem])
         return (SkipChan main sem)
    
    putSkipChan :: SkipChan a -> a -> IO ()
    putSkipChan (SkipChan main _) v = do
         (_, sems) <- takeMVar main
         putMVar main (v, [])
         mapM_ (sem -> putMVar sem ()) sems
    
    getSkipChan :: SkipChan a -> IO a
    getSkipChan (SkipChan main sem) = do
         takeMVar sem
         (v, sems) <- takeMVar main
         putMVar main (v, sem:sems)
         return v
    
    dupSkipChan :: SkipChan a -> IO (SkipChan a)
    dupSkipChan (SkipChan main _) = do
         sem <- newEmptyMVar
         (v, sems) <- takeMVar main
         putMVar main (v, sem:sems)
         return (SkipChan main sem)