有没有办法增加一个时间间隔,RTS 根据该时间间隔来判断线程在 STM 事务中无限期阻塞?
这是我的代码:
import Control.Concurrent (ThreadId)
import Control.Concurrent.MVar (MVar,newMVar,withMVar)
import Control.Concurrent.STM
import qualified Control.Concurrent.ThreadManager as TM
data ThreadManager = ThreadManager { tmCounter::TVar Int, tmTM::MVar TM.ThreadManager }
data Settings = Settings {
maxThreadsCount::Int }
createThreadManager :: Settings -> IO ThreadManager
createThreadManager s = do
counter <- atomically $ newTVar (maxThreadsCount s)
tm <- TM.make >>= newMVar
return $ ThreadManager counter tm
forkManaged :: ThreadManager -> IO () -> IO ThreadId
forkManaged tm fn = do
atomically $ do
counter <- readTVar $ tmCounter tm
check $ counter > 0
writeTVar (tmCounter tm) (counter - 1)
withMVar (tmTM tm) $ \thrdmgr -> TM.fork thrdmgr $ do
fn
atomically $ do
counter <- readTVar $ tmCounter tm
writeTVar (tmCounter tm) (counter + 1)
fork管理确保同时运行的托管线程的数量不超过最大线程数。在重负载之前它工作正常。在重负载下,RTS 会引发异常。我认为在重负载下,在资源的硬并发竞争中,某些线程根本没有时间访问 STM 上下文。所以我认为,增加RTS决定抛出此异常的时间间隔可能会解决问题。
丹尼尔·瓦格纳是对的。该决定不是在超时的情况下做出的。 rts中的相关代码位于Schedule.c https://github.com/ghc/ghc/blob/53b63e3034e280cd440e75a2a5ab35742263378e/rts/Schedule.c#2400
See the resurrectThreads
抛出异常的函数。注释中描述了这只会抛出到GC后发现是垃圾的线程。 ezyang 描述了这对于 mvar 的作用:http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/ http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/
[有关的不良猜测check
当我检查其来源并意识到这只是一个简单的防护/重试而不是早期论文中描述的内容时,将其删除 - 哎呀!我现在怀疑丹尼尔·瓦格纳在这里也是正确的,问题是计数器没有增加。]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)