¿Hay alguna manera de aumentar un intervalo de tiempo, en función del cual el RTS decide que el hilo ha bloqueado indefinidamente en una transacción STM? Aquí está mi código:Haskell: hilo bloqueado indefinidamente en una transacción 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 se asegura de que la cantidad de hilos que se ejecutan simultáneamente administrados no exceda maxThreadsCount. Funciona bien hasta una carga pesada. Bajo carga pesada, RTS arroja una excepción. Creo que bajo mucha carga, en la competencia concurrente de recursos, algunos de los hilos simplemente no tienen tiempo para acceder al contexto de STM. Entonces, creo que aumentar el intervalo de tiempo cuando RTS decide lanzar esta excepción puede resolver el problema.
¿Estás seguro de que la decisión se toma con tiempos de espera? Pensé que usaba sus registros para decidir cuándo dos 'retry's estaban esperando el uno al otro. –
@ Daniel: Daniel, actualicé la pregunta proporcionando mi código usando STM. Es por eso que creo que el problema con el tiempo de espera. –
¿Es posible que 'fn' arroje una excepción y evite que el contador se incremente? –