gpt4 book ai didi

multithreading - cancel 和 uninterruptibleCancel 之间的区别(来自 Async 库)

转载 作者:行者123 更新时间:2023-12-03 12:51:44 26 4
gpt4 key购买 nike

语境:

我试图了解 cancel 之间的区别和 uninterruptibleCancel 来自 Control.Concurent.Async包裹。我相信这与 mask 的基本概念有关。 , uninterruptibleMask , 和 interruptible operations .这就是我所理解的:

  • 异步异常由线程 A 抛出,但需要由线程 B 处理。这正是 throwTo 做。在某种程度上,这也可以被认为是一种线程间通信的形式。
  • 一个线程使用异步异常来杀死/取消另一个线程。
  • 处理异步异常会在目标/接收线程中产生问题,因为通常不希望在代码中的任何随机点引发异常。一推 try/catch围绕某些操作,只期望/处理某些异常。但是,当目标线程可能在执行中的任何点时,可以传递异步异常。
  • mask允许用于保护目标/接收线程中的关键部分免受异步异常的传递。受 mask 保护的操作在调用 restore 之前不需要处理异步异常.

  • 此时 uninterruptibleMask进入画面,我开始失去情节。我认为 mask 的全部要点是在执行一段 protected 代码时不传递异步异常。但是,以下是文档关于“可中断操作”的说法:

    It is useful to think of mask not as a way to completely prevent asynchronous exceptions, but as a way to switch from asynchronous mode to polling mode. The main difficulty with asynchronous exceptions is that they normally can occur anywhere, but within a mask an asynchronous exception is only raised by operations that are interruptible (or call other interruptible operations). In many cases these operations may themselves raise exceptions, such as I/O errors, so the caller will usually be prepared to handle exceptions arising from the operation anyway. To perform an explicit poll for asynchronous exceptions inside mask, use allowInterrupt.



    问题:
  • 即使在受 mask 保护的代码块内, 如果有一些地方可以安全地处理异步异常,可以调用 allowInterrupt .这隐含的意思是,除非 allowInterrupt被调用,执行时不会传递异步异常 mask编代码。那么,uninterruptibleMask 的目的是什么? ?
  • 因此,uninterruptibleCancel 的需求是什么? ? IIUC,线程 A 试图取消线程 B,但线程 A 本身试图保护自己免受某种异步异常的影响,这可能是由第三个线程 C 发起的,对吗?在 cancel 的代码中(如下所示),哪个部分如此重要以至于需要对异步异常进行最终形式的保护?不是throwTo原子/屏蔽操作本身?此外,即使在执行 waitCatch 时将异步异常传递给线程 A ,有什么区别?实际上,如果我想一想,为什么我们甚至需要 mask首先是这段代码(更不用说uninterruptibleMask)?
  • cancel a@(Async t _) = throwTo t AsyncCancelled <* waitCatch a

    最佳答案

    在没有屏蔽的情况下,异步异常可以在任何地方发生。在 mask 下,异步异常只能出现在可中断的 Action (通常是阻塞的)中。在 uninterruptibleMask 下,异步异常完全不存在。另外,请注意 allowInterrupt只是可中断的 Action 之一;还有很多,例如takeMVar .只需 mask , 例如无法阻止 MVar不向异常(exception)敞开心扉,而是uninterruptibleMask让你这样做(尽管你不应该这样做)。
    uninterruptibleCancel很有用,因为 cancel等待目标线程完成。这是一个阻塞操作,所以按照惯例,它也是可中断的。因此,当您使用 cancel ,无论你是 mask,你都会接受意外的异常。编辑与否。当您使用 uninterruptibleCancel ,您可以 100% 保证不会出现异常。就是这样。请记住,异常是非本地的;即使 cancel 中没有任何内容很关键,让它不 protected 意味着异常可能会泄漏到原来的东西中。

    mask $ do
    cancel something -- whoops, this can receive an exception, even though it's masked
    someCleanup -- therefore this might not get called

    对比
    mask $ do
    uninterruptibleCancel something -- no exceptions
    someCleanup -- so this will definitely happen (assuming the target thread ends)

    关于multithreading - cancel 和 uninterruptibleCancel 之间的区别(来自 Async 库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58360596/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com