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 - Fatal编程技术网

Haskell 更新MVar引发异常

Haskell 更新MVar引发异常,haskell,Haskell,鉴于: 我试着打电话给putMVar: 但它失败了 λ: >:t putMVar putMVar :: MVar a -> a -> IO () λ: >:t x x :: IO (MVar [Char]) 为什么它失败了?我如何用foo而不是foo更新x?让我们查看文档: MVar发音为em var是一个同步变量,用于 并发线程之间的通信。它可以被认为是一个 框,可以是空的或满的 及 创建包含所提供值的MVar 及 将值放入MVar中。如果MVar当前已满,则put

鉴于:

我试着打电话给putMVar:

但它失败了

λ: >:t putMVar
putMVar :: MVar a -> a -> IO ()

λ: >:t x
x :: IO (MVar [Char])

为什么它失败了?我如何用foo而不是foo更新x?

让我们查看文档:

MVar发音为em var是一个同步变量,用于 并发线程之间的通信。它可以被认为是一个 框,可以是空的或满的

创建包含所提供值的MVar

将值放入MVar中。如果MVar当前已满,则putMVar将 等到它变空

putMVar还有两个重要特性:

putMVar是单唤醒。也就是说,如果有多个线程 在putMVar中阻塞,并且MVar变为空,则只有一个线程将 被叫醒。运行时保证唤醒的线程完成 它的putMVar操作。在MVar上阻止多个线程时, 他们按先进先出的顺序被叫醒。这有助于提供公平性 使用MVAR构建的抽象的属性


梅尔波默恩的回答包含了正确的解释。对于引用的文档,我的答案保留在这里。

让我们查找文档:

MVar发音为em var是一个同步变量,用于 并发线程之间的通信。它可以被认为是一个 框,可以是空的或满的

创建包含所提供值的MVar

将值放入MVar中。如果MVar当前已满,则putMVar将 等到它变空

putMVar还有两个重要特性:

putMVar是单唤醒。也就是说,如果有多个线程 在putMVar中阻塞,并且MVar变为空,则只有一个线程将 被叫醒。运行时保证唤醒的线程完成 它的putMVar操作。在MVar上阻止多个线程时, 他们按先进先出的顺序被叫醒。这有助于提供公平性 使用MVAR构建的抽象的属性

梅尔波默恩的回答包含了正确的解释。对于引用的文档,我的答案留在这里。

x不是MVar。它是一个创建MVar的操作,即它是newMVar的另一个名称

x>>=\y->putMVar y foo是一个创建MVar并将其命名为y的操作。然后它尝试将foo放入MVar中。但是,y已经包含,所以putMVar块。它不会简单地永远阻塞,因为在这个操作中y是一个局部变量,这意味着没有其他人可以访问它,也不存在读取器。putMVar检测到这种死锁情况并引发异常

你应该做的是从以下几点开始:

putMVar :: MVar a -> a -> IO ()
并在

takeMVar x
MVar不支持一步替换现有值;首先必须将其取出,然后放入新值。

x不是MVar。它是一个创建MVar的操作,即它是newMVar的另一个名称

x>>=\y->putMVar y foo是一个创建MVar并将其命名为y的操作。然后它尝试将foo放入MVar中。但是,y已经包含,所以putMVar块。它不会简单地永远阻塞,因为在这个操作中y是一个局部变量,这意味着没有其他人可以访问它,也不存在读取器。putMVar检测到这种死锁情况并引发异常

你应该做的是从以下几点开始:

putMVar :: MVar a -> a -> IO ()
并在

takeMVar x

MVar不支持一步替换现有值;您首先必须将其取出,然后放入一个新值。

我认为您使用一个值创建新的MVar-您需要先提取该值,然后再将其放入其中!其目的是:MVar的语义是一个由互斥体保护的1位队列。您将创建一个包含的完整队列。在使用takeMVar首先清空队列之前,您不能对任何其他内容进行排队。否则putMVar将等待其他人首先清空队列。在你的例子中,GHC注意到没有人可以清空队列,并触发异常,而不是永远被卡住。运行时正试图保持友好,在这里报告错误。我认为你用一个值创建新的MVar-你需要先提取该值,然后再将其放入其中!其目的是:MVar的语义是一个由互斥体保护的1位队列。您将创建一个包含的完整队列。在使用takeMVar首先清空队列之前,您不能对任何其他内容进行排队。否则putMVar将等待其他人首先清空队列。在您的例子中,GHC注意到没有人可以清空队列,并触发异常,而不是永远被卡住运行时正试图友好地报告错误。
putMVar :: MVar a -> a -> IO ()
x <- newMVar ""
takeMVar x
putMVar x "foo"