Multithreading 取消和不间断取消之间的差异(来自异步库) 背景:

Multithreading 取消和不间断取消之间的差异(来自异步库) 背景:,multithreading,haskell,concurrency,Multithreading,Haskell,Concurrency,我试图理解Control.Concurent.Async包和之间的区别。我相信这与,和的基本概念有关。以下是我的理解: 异步异常由线程A抛出,但需要由线程B处理。这正是它的作用。在某种程度上,这也可以看作是线程间通信的一种形式。 一个线程使用异步异常终止/取消另一个线程。 处理AYSNChrous异常会在目标/接收线程中产生问题,因为通常不希望在代码中的任意点引发异常。人们将try/catch放在某些操作周围,只期望/处理某些异常。但是,当目标线程可以在执行过程中的任何一点上时,可以传递异步异常

我试图理解Control.Concurent.Async包和之间的区别。我相信这与,和的基本概念有关。以下是我的理解:

异步异常由线程A抛出,但需要由线程B处理。这正是它的作用。在某种程度上,这也可以看作是线程间通信的一种形式。 一个线程使用异步异常终止/取消另一个线程。 处理AYSNChrous异常会在目标/接收线程中产生问题,因为通常不希望在代码中的任意点引发异常。人们将try/catch放在某些操作周围,只期望/处理某些异常。但是,当目标线程可以在执行过程中的任何一点上时,可以传递异步异常。 掩码允许用于保护目标/接收线程中的关键部分不受异步异常传递的影响。受掩码保护的操作在调用restore之前不需要处理异步异常。 在这一点上,不间断任务进入画面,我开始失去情节。我认为mask的全部目的是在执行受保护的代码时不传递异步异常。但是,以下是文档中关于可中断操作的说明:

最好不要将掩码看作是完全防止异步异常的一种方法,而是将其看作是从异步模式切换到轮询模式的一种方法。异步异常的主要困难在于,它们通常可以发生在任何地方,但在掩码中,异步异常仅由可中断的操作或调用其他可中断的操作引发。在许多情况下,这些操作本身可能引发异常,例如I/O错误,因此调用方通常会准备好处理由该操作引起的异常。若要在掩码内对异步异常执行显式轮询,请使用allowInterrupt

问题: 即使在受掩码保护的代码块中,如果在某些点上处理异步异常是安全的,也可以调用AllowerRunp。这意味着,除非调用AllowerIntrup,否则在执行屏蔽代码时将不会传递异步异常。那么,不间断提问的目的是什么? 因此,不间断取消的必要性是什么?IIUC,线程A试图取消线程B,但线程A本身试图保护自己不受某种异步异常的影响,这种异常可能由第三个线程C启动,对吗?在下面给出的cancel代码中,哪一部分是如此关键,以至于需要针对异步异常提供最终形式的保护?这不是一个原子/屏蔽操作本身吗?此外,即使在执行waitCatch时将异步异常传递给thread-A,它又有什么区别呢?事实上,如果我想一想,为什么我们一开始就需要屏蔽这段代码,更不用说不间断提问了?
在无掩蔽的情况下,异步异常可以在任何地方发生。在掩码下,异步异常只能出现在通常阻塞的可中断操作中。在不间断任务下,异步异常是完全不可能出现的。另外,请注意AllowerRunp只是可中断操作之一;还有很多,例如takeMVar。例如,使用just mask时,如果不向异常开放,就不可能在MVar上进行阻止,但“不间断任务”允许您执行,尽管您不应该这样做

不间断取消很有用,因为取消等待目标线程完成。这是一个阻塞操作,因此,按照惯例,它也是可中断的。因此,当您使用cancel时,无论您是否被屏蔽,您都会收到意外的异常。使用“不间断取消”时,100%保证不会出现异常。就这样。请记住,例外情况是非本地的;即使cancel中的任何内容都不重要,将其保留为不受保护的状态也意味着异常可能会泄漏到不重要的内容中

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

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)