C'è un modo per aumentare un intervallo di tempo, in base al quale l'RTS decide che il thread si è bloccato indefinitamente in una transazione STM? Ecco il mio codice:Haskell: thread bloccato a tempo indeterminato in una transazione 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 fa in modo che quantità di esecuzione contemporaneamente thread gestiti non superi maxThreadsCount. Funziona bene fino a carichi pesanti. Sotto carico pesante RTS genera un'eccezione. Penso che sotto carico pesante, sulla concorrenza concomitante per le risorse, alcuni thread non abbiano tempo per accedere al contesto STM. Quindi penso che aumentare l'intervallo di tempo quando RTS decide di lanciare questa eccezione può risolvere il problema.
Sei sicuro che la decisione sia presa con i timeout? Ho pensato che usasse i suoi registri per decidere quando due 'retry' si stavano aspettando a vicenda. –
@ Daniel: Daniel, ho aggiornato la domanda fornendo il mio codice usando STM. Questo è il motivo per cui penso al problema con il timeout. –
È possibile che 'fn' stia lanciando un'eccezione e impedendo l'incremento del contatore? –