gpt4 book ai didi

multithreading - 使用TVar时,如何等待forM_完成?

转载 作者:行者123 更新时间:2023-12-03 13:19:11 25 4
gpt4 key购买 nike

我正在编写一个函数,在其中使用forM_处理列表,并将结果附加到TVar列表中:

import Control.Concurrent.STM
import Control.Concurrent.STM.TVar
import Control.Concurrent (forkIO)
import Control.Monad (forM_)

insert :: a -> [a] -> [a]
insert = (:) -- stub

my_func_c :: (a -> a) -> [a] -> IO [a]
my_func_c my_function arr = do

res_var <- atomically $ newTVar ([]::[a])

forkIO $ forM_ arr $ \x -> atomically $ do
let y = id $! my_function x
modifyTVar res_var (insert y)

atomically $ readTVar res_var

如果我使用 -threaded进行编译,则结果始终为空。如何等待线程完成?我不能使用 MVarAsync。我必须使用 TVar或其他基于 TVar的数据结构来解决此问题

最佳答案

惯用的解决方案是使用 TMVar :

my_func_c :: (a -> a) -> [a] -> IO [a]
my_func_c my_function arr = do
res_var <- atomically $ newTVar []
finished <- atomically $ newEmptyTMVar

forkIO $ do
forM_ arr $ \x -> atomically $ do
let y = id $! my_function x
modifyTVar res_var (insert y)
atomically $ putTMVar finished ()

atomically $ takeTMVar finished >> readTVar res_var

但是,如果实际上只允许您使用 TVar,则可以使用 TMVar ()模拟 TVar Bool:
my_func_c :: (a -> a) -> [a] -> IO [a]
my_func_c my_function arr = do
res_var <- atomically $ newTVar []
finished <- atomically $ newTVar False

forkIO $ do
forM_ arr $ \x -> atomically $ do
let y = id $! my_function x
modifyTVar res_var (insert y)
atomically $ writeTVar finished True

atomically $ waitTVar finished >> readTVar res_var

waitTVar :: TVar Bool -> STM ()
waitTVar tv = do
finished <- readTVar tv
unless finished retry

实际上, TMVar a is just a TVar (Maybe a) (即 TMVar ()TVar (Maybe ())TVar Bool)与 takeTMVar doing a readTVar and a retry 在一起,因此以上两种解决方案在操作上是完全等效的。

关于multithreading - 使用TVar时,如何等待forM_完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43669931/

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