【发布时间】:2011-10-22 20:26:55
【问题描述】:
有没有什么办法可以增加一个时间间隔,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)
forkManaged 确保同时运行的托管线程的数量不超过 maxThreadsCount。它工作正常,直到重载。在重负载下,RTS 会引发异常。我认为在重负载下,在激烈的并发资源竞争中,一些线程没有时间访问 STM 上下文。所以我认为,增加 RTS 决定抛出此异常的时间间隔可能会解决问题。
【问题讨论】:
-
您确定该决定是通过超时做出的吗?我认为它使用日志来决定两个
retrys 何时相互等待。 -
@Daniel:丹尼尔,我已经通过使用 STM 提供我的代码更新了这个问题。这就是为什么我认为超时的问题。
-
fn是否有可能抛出异常,并阻止计数器递增? -
@Daniel:我是否正确,如果引发了异常,并且没有在我的代码中捕获,那么我应该在控制台中看到它吗?实际上那些 fn 在 IO 中做了一些动作,但是这些动作被包裹在 Control.Exception.catch 中,我在控制台中没有看到任何抱怨。
标签: multithreading haskell stm