haskell - 如何使括号免受异步异常的影响?

标签 haskell asynchronous exception concurrency

每篇有关异常的 Haskell 文章都重复简单的模式:使用括号函数分配/释放资源,您将是安全的。
我有一个担忧,因为我测试了它的行为并检测到线程在发布部分工作时会出现异步异常。

import Control.Exception
import Control.Concurrent

main = do
  tid <- forkIO myThread
  threadDelay 100000
  throwTo tid StackOverflow
  threadDelay 1000000

myThread = 
  bracket 
    (putStrLn "NEW")
    (\() -> threadDelay 500000 >> putStrLn "CLEAN")
    (\() -> putStrLn "USE")
在上面的代码片段中,由于异步异常而没有打印“CLEAN” - 所以资源泄漏!如何声称它是安全的?
我不知道这一定是一个原因。
为了确保安全,我需要将每次清洁都包裹在 mask 内。它看起来很笨拙。

最佳答案

To make it safe as I see it I need to wrap every cleaning inside mask.


不幸的是,我认为答案正是如此。如果您有必须为资源安全而运行的清理操作,并且您希望通过异步异常来维护资源安全,那么您必须在清理期间使用不间断掩码。
这类似于将自己限制在 Unix/Linux 信号处理程序中的信号安全函数或 C++ 析构函数中的异常安全函数,除了这里的标准是“不可中断”,无论是您调用的函数所固有的,还是通过屏蔽(可能更容易获得正确的)。
或者,您可以使用 bracket 来自 unliftio包,它在其清理处理程序中使用不间断屏蔽。 (与您的问题无关,此包提供了 MonadUnliftIO 类,用于通过无状态包装器提升 IO 操作;它是更复杂的 MonadBaseControl 的受限替代方案,来自 monad-control,它处理任何基本 monad 上的有状态包装器。)

关于haskell - 如何使括号免受异步异常的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64468126/

相关文章:

java - 异步任务停止工作,在使用断点调试时工作 - Android

oop - 什么是 'exceptional' ?

haskell - 有选择地包装类实例的正确方法(或 "lift"函数,如 `sortBy` 、 `minimumBy` ……自动)

javascript - 带有标志变量的递归和异步方法

haskell - Haskell 中 `==` 的类型应该是 `Eq a b => a -> b -> Bool`

javascript - Nodejs 循环困惑

c# - 异常句柄

python - 我得到 "TypeError: exceptions must derive from BaseException"即使我确实定义了它

haskell - 在 Haskell 中组合 monad

haskell - 类型构造函数柯里化(Currying)? (尝试创建一个接受一种类型的数据构造函数,另一个接受两种类型的数据构造函数)