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
Multithreading Haskell MVar无限期阻塞,而不涉及MVar_Multithreading_Haskell_Recursion_Concurrency_Deadlock - Fatal编程技术网

Multithreading Haskell MVar无限期阻塞,而不涉及MVar

Multithreading Haskell MVar无限期阻塞,而不涉及MVar,multithreading,haskell,recursion,concurrency,deadlock,Multithreading,Haskell,Recursion,Concurrency,Deadlock,TL;DR:我有一个haskell项目,其中所有内容都在一个线程中,没有任何并发性,但崩溃如下: program1: thread blocked indefinitely in an MVar operation 详细说明: 我试图在工作时找到bug,这取决于另一个库,timeless。您会注意到,所有并发代码都被注释掉了,对“无时间回购”进行grep将表明不涉及任何并发代码。然后我对这次崩溃完全感到困惑,我不知道如何获得更详细的信息,比如堆栈跟踪。我尝试使用一些RTS参数运行: $ sta

TL;DR:我有一个haskell项目,其中所有内容都在一个线程中,没有任何并发性,但崩溃如下:

program1: thread blocked indefinitely in an MVar operation
详细说明:

我试图在工作时找到bug,这取决于另一个库,timeless。您会注意到,所有并发代码都被注释掉了,对“无时间回购”进行grep将表明不涉及任何并发代码。然后我对这次崩溃完全感到困惑,我不知道如何获得更详细的信息,比如堆栈跟踪。我尝试使用一些RTS参数运行:

$ stack exec -- Tutorial1 +RTS -p -M4m -xc
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: 
  FRP.Timeless.Internal.Signal.loop.\,
  called from FRP.Timeless.Internal.Signal.loop,
  called from FRP.Timeless.state,
  called from FRP.Timeless.Internal.Signal.first.\,
  called from FRP.Timeless.Internal.Signal.first,
  called from FRP.Timeless.Internal.Signal...\,
  called from FRP.Timeless.Internal.Signal..,
  called from Tutorial1.test0,
  called from FRP.Timeless.Internal.Signal.stepSignal.step,
  called from FRP.Timeless.Internal.Signal.stepSignal,
  called from FRP.Timeless.Run.runBox,
  called from Tutorial1.main
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: 
  FRP.Timeless.Internal.Signal.loop.\,
  called from FRP.Timeless.Internal.Signal.loop,
  called from FRP.Timeless.state,
  called from FRP.Timeless.Internal.Signal.first.\,
  called from FRP.Timeless.Internal.Signal.first,
  called from FRP.Timeless.Internal.Signal...\,
  called from FRP.Timeless.Internal.Signal..,
  called from Tutorial1.test0,
  called from FRP.Timeless.Internal.Signal.stepSignal.step,
  called from FRP.Timeless.Internal.Signal.stepSignal,
  called from FRP.Timeless.Run.runBox,
  called from Tutorial1.main
Tutorial1: thread blocked indefinitely in an MVar operation
而且我找不到什么是
THUNK_STATIC
,因为谷歌上没有关于它的报道。根据我的猜测,这个bug可能与最初来自Netwire的神奇的
ArrowLoop
有关,但我真的无法理解它

我将整个永恒的测试用例剥离到最小的样本中,该样本是自包含的,并且包含bug。我再也不能拆开
信号了,因为它们最初是从Netwire分叉的,我不完全理解ArrowLoop的东西在引擎盖下是如何工作的

更新我使示例变得更小。我还确认了这个bug在没有
-threaded
标志的情况下存在

{-# LANGUAGE Arrows #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE GADTs #-}

import Prelude hiding ((.),id)
import Control.Applicative
import Control.Arrow
import Control.Monad
import Control.Monad.Fix
-- import Data.Monoid
import Control.Category
import Data.Maybe


---------
-- Stripped down Timeless here
---------
data Signal a b where
  SGen ::
    (Maybe a -> IO (Maybe b, Signal a b)) -> Signal a b


instance Category Signal where
    id = SGen (\ma -> return (ma, id))
    s2 . s1 = SGen $ \mx0 -> do
                (mx1, s1') <- stepSignal s1 mx0
                (mx2, s2') <- stepSignal s2 mx1
                mx2 `seq` return (mx2, s2'. s1')

instance Arrow Signal where
    arr f = SGen $ \ma -> case ma of
      Just a -> return (Just (f a), arr f)
      Nothing -> return (Nothing, arr f)

    first s' =
        SGen $ \mxy' ->
            fmap (\(mx, s) -> lstrict (liftA2 (,) mx (fmap snd mxy'), first s))
                  (stepSignal s' (fmap fst mxy'))

instance ArrowLoop Signal where
  loop s =
    SGen $ \mx ->
      fmap (fmap fst ***! loop) .
      mfix $ \ ~(mx',_) ->
        let d | Just (_,d) <- mx' = d
              | otherwise = error "Feedback broken by inhibition"
        in stepSignal s (fmap (,d) mx)

-- | Steps a signal in certain time step
stepSignal ::
              Signal a b
           -- ^ Signal to be stepped
           -> Maybe a
           -- ^ Input
           -- | Stateful output
           -> IO (Maybe b, Signal a b)
stepSignal s Nothing = return (Nothing, s)
stepSignal s (Just x) = x `seq` step s (Just x)
  where
    step (SGen f) = f

-- | Left-strict version of '&&&' for functions.
(&&&!) :: (a -> b) -> (a -> c) -> (a -> (b, c))
(&&&!) f g x' =
    let (x, y) = (f x', g x')
    in x `seq` (x, y)


-- | Left-strict version of '***' for functions.
(***!) :: (a -> c) -> (b -> d) -> ((a, b) -> (c, d))
(***!) f g (x', y') =
    let (x, y) = (f x', g y')
    in x `seq` (x, y)

-- | Left strict tuple
lstrict :: (a,b) -> (a,b)
lstrict (x,y) = x `seq` (x,y)


-- | Make a pure stateful signal from given transition function
mkPure :: (a -> (Maybe b, Signal a b)) -> Signal a b
mkPure f =
  SGen $ \mx ->
  case mx of
    Just x -> return . lstrict $ f x

-- | Make a pure stateful signal from given signal function
mkSF :: (a -> (b, Signal a b)) -> Signal a b
mkSF f = mkPure (lstrict . first Just . f)

-- | Make a pure stateless signal from given signal function
mkSF_ :: (a -> b) -> Signal a b
mkSF_ = arr

delay :: a -> Signal a a
delay x' = mkSF $ \x -> (x', delay x)

-- | Make a stateful wire from chained state transition
-- function. Notice that the output will always be the new value
mkSW_ :: b -> (b -> a -> b) -> Signal a b
mkSW_ b0 f = mkSF $ g b0
    where
      g b0 x = let b1 = f b0 x in
                   lstrict (b1, mkSW_ b1 f)

-- | This command drives a black box of signal network. The driver
-- knows nothing about the internals of the network, only stops when
-- the network is inhibited.
runBox :: Signal () () -> IO ()
runBox n = do
 (mq, n') <- stepSignal n (Just ())
 case mq of
   Just _ -> n' `seq` runBox n'
   Nothing -> return ()

-- | Holds a discrete value to be continuous. An initial value must be given
hold :: a -> Signal (Maybe a) a
hold a0 = mkSW_ a0 fromMaybe

-- | Takes a snapshot of b when an event a comes. Meanwhile, transform the
-- 'Stream' with the 'Cell' value
snapshot :: ((a,b) -> c) -> Signal (Maybe a, b) (Maybe c)
snapshot f = mkSF_ $ \(ma, b) ->
  case ma of
    Just a -> Just $ f (a,b)
    Nothing -> Nothing

state :: s -> ((a, s) -> s) -> Signal (Maybe a) s
state s0 update = loop $ proc (ma, s) -> do
  sDelay <- delay s0 -< s
  s' <- hold s0 <<< snapshot update -< (ma, sDelay)
  returnA -< (s', s')

------
-- Stripped down Timeless ends
------

-- | Problematic Arrow
test0 = proc () -> do
  s <- state 0 (\(_, coin) -> coin + 1) -< Nothing
  returnA -< ()


main :: IO ()
main = runBox test0
{-#语言箭头#-}
{-#语言元组{-}
{-#语言GADTs}
导入前奏隐藏((.)id)
导入控制
导入控制。箭头
进口管制
导入控制.Monad.Fix
--导入数据.幺半群
进口管制.类别
导入数据,也许吧
---------
--在这里剥去永恒的外衣
---------
数据信号a b,其中
斯根::
(可能a->IO(可能b,信号AB))->信号AB
实例类别信号在哪里
id=SGen(\ma->return(ma,id))
s2。s1=SGen$\mx0->do
(mx1,s1’)
fmap(fmap fst***!循环)。
mfix$\~(mx',\)>
让d |只是(d)c)->(b->d)->(a,b)->(c,d))
(***!)fg(x',y')=
设(x,y)=(fx',gy')
在x`seq`(x,y)中
--|左严格元组
(a,b)->(a,b)
lstrict(x,y)=x`seq`(x,y)
--|从给定的转换函数生成纯状态信号
mkPure::(a->(可能是b,信号ab))->信号ab
mkf=
SGen$\mx->
案例mx
只需x->返回。价格$f x
--|从给定信号函数生成纯状态信号
mkSF::(a->(b,信号a b))->信号a b
mkSF f=mkPure(lstrict.first Just.f)
--|从给定信号函数生成纯无状态信号
mkSF::(a->b)->信号a b
mkSF_uu=arr
延迟::a->信号a
延迟x'=mkSF$\x->(x',延迟x)
--|从链式状态转换生成有状态的连线
--功能。请注意,输出将始终是新值
mkSW::b->(b->a->b)->信号a b
mkSW_ub0f=mkSF$g b0
哪里
g b0 x=设b1=f b0 x英寸
lstrict(b1,mkSW_uB1F)
--|此命令驱动信号网络的黑匣子。司机
--对网络的内部结构一无所知,只在
--网络被禁止。
runBox::Signal()()->IO()
runBox n=do
(mq,n')n'`seq`runBox n'
无->返回()
--|将离散值保持为连续值。必须给出初始值
保持::a->信号(可能是a)a
保持a0=mkSW_uA0
--|在事件a发生时拍摄b的快照。同时,要转变观念
--具有“单元格”值的“流”
快照::((a,b)->c)->信号(可能a,b)(可能c)
快照f=mkSF\u$\(ma,b)->
马案
仅a->仅$f(a,b)
无->无
状态::s->((a,s)->s)->信号(可能是a)s
状态s0更新=循环$proc(ma,s)->do

sDelay你真的应该试着把它简化成一个小例子,你可以把它粘贴到你的问题主体中。我知道这可能很难,但必须有人这样做才能修复bug,甚至确定哪个包负责。这个问题可能非常有趣,但缺少信息。您应该在问题本身中提供问题代码的(最小化版本)。有关更多指南,请参阅,这是一个最小的示例。不需要外部库,对于
IO
,也不需要并发和MVar
mfix
。可能相关的问题:
stepSignal
中删除
seq
,以消除异常。我怀疑通过强制信号
fixIO的值