gpt4 book ai didi

multithreading - 从线程本身内部取消异步线程

转载 作者:行者123 更新时间:2023-12-04 04:26:52 25 4
gpt4 key购买 nike

有没有办法在 async 中使用 async 调用的线程中使用 cancel包裹?我可以看到您可以从线程外部取消它,但我想知道是否有一个 cancelSelf::IO () 函数可以停止其自身的执行。我可以将一些东西与唯一的id生成和Async线程引用的共享Map结合在一起,线程本身可以引用它,但这似乎太多了。我可以逃脱未捕获的异常或其他什么吗?

最佳答案

异步操作可以自行取消。不过,这涉及到一些技巧。

{-# LANGUAGE RecursiveDo #-}

import Control.Concurrent.Async

main :: IO ()
main = do
rec let doCancel = cancel calculate
calculate <- async doCancel
wait calculate

理论上,无需 RecursiveDo 即可做到这一点,但我从来不想写 mfix 手动表达(RecursiveDo 将脱糖绑定(bind)到什么)。

RecursiveDo允许您在 do block 内创建一组相互递归的定义,即使某些定义与 <- 绑定(bind)。有些是在 let 内定义的陈述。与往常一样,如果涉及真正的循环,计算就会发散。但在很多情况下,您想要做的只是能够引用其他内容的名称,例如上面的示例,以及 RecursiveDo工作得很好。

哦,还有the implementation of mfix for IO 很可怕。我很高兴我不必自己编写它。

-- 编辑--

由于几乎没有收到任何反馈,我意识到如何使用它来解决您的问题并不完全明显。这是一个扩展示例,使用组合器生成 Async可以自行取消:

{-# LANGUAGE RecursiveDo #-}

-- obviously want the async library
import Control.Concurrent.Async

-- used in selfCancelableAsync
import Control.Monad (forever)
import Control.Concurrent (threadDelay)

-- only used for demonstration
import System.Random (randomIO)

main :: IO ()
main = do
a <- selfCancelableAsync $ \selfCancel -> do
choice <- randomIO
if choice then return "Success!" else selfCancel
result <- wait a
putStrLn result

-- spawns an Async that has the ability to cancel itself by
-- using the action passed to the IO action it's running
selfCancelableAsync :: (IO a -> IO b) -> IO (Async b)
selfCancelableAsync withCancel = do
rec let doCancel = do
cancel calculate
-- This must never return to ensure it has the correct type.
-- It uses threadDelay to ensure it's not hogging resources
-- if it takes a moment to get killed.
forever $ threadDelay 1000

calculate <- async $ withCancel doCancel

return calculate

关于multithreading - 从线程本身内部取消异步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42664692/

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