TVar 阻止读取直到更改?

问题描述 投票:0回答:1

我正在尝试思考如何在 Haskell 中的线程之间正确通信。

我有多个线程读取某些状态,每当状态发生变化时,它们都需要进行一些更新。然后我有多个线程可以改变该状态。

我首先查看了 MVar,但这不行,因为它在写入时会阻塞,并且只有一个线程可以读取。

我发现的最好的东西是 TVar,我可以向它写入并从中读取当前状态。因此,我可以让读取的线程每秒左右轮询一次状态的更改(小延迟并不重要,线程可能会错过状态之间的情况也不重要)。那会起作用的。

但是,我想知道,有没有一种不需要轮询的方法?我可以使用其他一些原语吗?或者我可以“听” TVar 的方式?

haskell concurrency
1个回答
0
投票
当值与之前相同时,只需读取并

retry

onChanges :: Eq a => (a -> IO ()) -> TVar a -> IO b onChanges f tvar = readTVarIO tvar >>= go where go a = do a' <- atomically do a' <- readTVar tvar when (a == a') retry pure a' f a' go a'
别担心——这并不贵。每个

retry

都会阻塞,直到再次写入
TVar
。如果与运行 
f
 相比,相等性检查的成本较高,或者如果您想在每次写入时运行 
f
,即使值没有更改,您也可以在 
Int
 中存储 
TVar
 或类似内容已经被写入了多少次,并检查它来决定是否
retry

© www.soinside.com 2019 - 2024. All rights reserved.