了解并发代码中的BlockedIndefinitelyOnMVar

编程入门 行业动态 更新时间:2024-10-26 10:26:52
本文介绍了了解并发代码中的BlockedIndefinitelyOnMVar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我问这个问题 ghc用户邮件列表,并得到了一些有用的回应,但仍不明白在这段代码中发生了什么。

基本上,我想了解如何捕捉例外BlockedIndefinitelyOnMVar来恢复一个可能还没有被返回的锁,并且通常理解这个异常。

下面是一些单线程代码: p>

- 这只会引发一次异常并且成功恢复锁定: main1 = do lock< ; - newMVar() lockPrintgood1锁定 takeMVar锁定 putStrLnmain:锁定但未返回! - 引发异常并在此恢复锁定: lockPrintgood2锁定 - 未引发异常: lockPrintgood3锁定 readMVar锁定 putStrLn巨大成功 lockPrint :: String - > MVar() - > IO() lockPrint name v = takePrint`finally`把放在put = putMVar v()>> putStrLn(name ++:locked lock) takePrint = do e < - try $ takeMVar v :: IO(BlockedIndefinitelyOnMVar()) let printExc = putStrLn。 ((名称++:)++)。 show printSuccess = const $ putStrLn(name ++:success) printExc printSuccess e

以下是展示我不明白的行为的主版本。特别是我不太清楚为什么这个异常会在main中被提出,尽管我发现这些线程并没有像我想象的那样真正被安排好。

main0 = do lock< - newMVar() forkIO $ lockPrintgood1锁定 threadDelay 100000 takeMVar锁定 putStrLnmain:锁定但未返回! - 无限期地引发无限例外 forkIO $ lockPrintgood2锁定 - 如果我们成功的话,这应该不会引发异常: putStrLnmain:long pause ... threadDelay 2000000 readMVar lock putStrLn巨大成功

很抱歉,我无法提供一个更简单的例子。上面的代码是用下面的代码编译的: ghc --make -threaded -fforce-recomp experiments.hs

编辑:Edward Z. Yang写了一篇非常清晰的博客博文今天在这里。结果是,这个异常不能真正依赖于做任何事情。

解决方案

试图处理 BlockedIndefinitelyOnMVar 首先听起来不是一个好主意。使用 withMVar ,以确保始终返回 MVar 的内容。有了这个,你不应该首先得到这个异常,除非你有一个死锁(这应该被认为是一个错误,应该在代码中修复)。

I asked this question on the ghc-users mailing list and got some helpful responses, but still don't understand what is happening in this code.

Essentially I am trying to understand how I can catch the exception BlockedIndefinitelyOnMVar to restore a lock that may have not been returned, and to understand this exception in general.

Here is some single-threaded code that does just that:

-- This raises the exception only once and the lock is successfully restored: main1 = do lock <- newMVar () lockPrint "good1" lock takeMVar lock putStrLn "main: took lock but didn't return it!" -- exception is raised and lock is restored here: lockPrint "good2" lock -- no exception raised: lockPrint "good3" lock readMVar lock putStrLn "great success" lockPrint :: String -> MVar () -> IO () lockPrint name v = takePrint `finally` put where put = putMVar v () >> putStrLn (name++": replaced lock") takePrint = do e <- try $ takeMVar v :: IO (Either BlockedIndefinitelyOnMVar ()) let printExc = putStrLn . ((name++": ")++) . show printSuccess = const $ putStrLn (name++": success") either printExc printSuccess e

And here is the version of main that exhibits the behavior I don't understand. In particular I'm not quite sure why the exception is being raised in main, although I see that the threads aren't really being scheduled as I imagine.

main0 = do lock <- newMVar () forkIO $ lockPrint "good1" lock threadDelay 100000 takeMVar lock putStrLn "main: took lock but didn't return it!" -- raises blocked indefinitely exception forkIO $ lockPrint "good2" lock -- this should raise no exception if we were successful above: putStrLn "main: long pause..." threadDelay 2000000 readMVar lock putStrLn "great success"

I'm sorry I'm having trouble coming up with a simpler example. The above was compiled with: ghc --make -threaded -fforce-recomp experiments.hs

EDIT: Edward Z. Yang wrote a really lucid blog post on this today here. The upshot being that this exception can't really be relied on for doing anything fancy.

解决方案

Trying to handle BlockedIndefinitelyOnMVar doesn't sound like a good idea in the first place. It's easier to use withMVar to ensure that the contents of the MVar is always returned. With that, you shouldn't get this exception in the first place, unless you have a deadlock (which should be considered a bug and should be fixed in the code).

更多推荐

了解并发代码中的BlockedIndefinitelyOnMVar

本文发布于:2023-07-30 00:44:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1245040.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   BlockedIndefinitelyOnMVar

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!