【问题标题】:How to enforce full evaluation inside async?如何在异步中强制执行全面评估?
【发布时间】:2020-10-16 13:28:55
【问题描述】:

我正在使用异步库并试图在实践中找出它的 API。我注意到一个我没想到的奇怪行为。它看起来像一个错误,但也许它是一个功能,我只需要知道一个解决方法。

import Control.Concurrent
import Control.Concurrent.Async

> withAsync (putStrLn "HELLO") (\_ -> putStrLn "WORLD")
WORLHEDL

上面的 sn-p 工作得很好 - 两条线都执行了,但更复杂的异步主体被部分评估。

> withAsync (putStrLn "XXXXXXXXXX" >> putStrLn "HELLO") (\_ -> putStrLn "WORLD")
WOXRXLXDX

看,第二个 putStrLn 没有被执行。 我想我需要将整个异步主体包装在某种 bnf 中,但无论如何它看起来很奇怪。为什么 withAsync 不为我这样做?


forkIO 工作得恰到好处,但我不想为 unlifting 烦恼。 async 具有自动传播 monad 的对库 unlift-async。

forkIO (Prelude.putStrLn "XXXXXXXXXX" >> Prelude.putStrLn "HELLO")
ThreadXIXdX X1X1X3X
XXX
HELLO

我找到了带有叉子功能的提升底座。它作为 forkIO 工作并将父 monad 传递给子线程。

【问题讨论】:

    标签: haskell asynchronous lazy-evaluation ghc


    【解决方案1】:

    withAsync 在主线程(第二个参数)终止时中断分叉线程(第一个参数)。这在documentation of withAsync 中是明确的:

    当函数返回或抛出异常时,在Async上调用uninterruptibleCancel

    (...) 这是async 的一个有用变体,可确保Async 永远不会意外运行。

    如果您只想分叉一个线程,请使用async

    async (putStrLn "XXXXXXXX" >> putStrLn "WORLD") >> putStrLn "HELLO"
    

    【讨论】:

      猜你喜欢
      • 2017-07-31
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多