Haskell: поток заблокирован на неопределенное время в транзакции STM - PullRequest
10 голосов
/ 23 октября 2011

Есть ли способ увеличить временной интервал, на основании которого 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 . Работает нормально до большой нагрузки. Под большой нагрузкой РТС выдает исключение. Я думаю, что при большой нагрузке, в условиях жесткой параллельной конкуренции за ресурсы, некоторые потоки просто не успевают получить доступ к контексту STM. Поэтому я думаю, что увеличение временного интервала, когда RTS решит выбросить это исключение, может решить проблему.

1 Ответ

7 голосов
/ 26 октября 2011

Даниэль Вагнер прав. Решение не принято с таймаутами. Соответствующий код в rts находится в Schedule.c

См. Функцию resurrectThreads, где выдается исключение. Комментарий описывает, что это только брошено темам, которые, как находят, были мусором после GC. Эзян описал, как это работает для Мварса: http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/

[плохое предположение относительно check убрано, когда я проверил его источник и понял, что это была просто защита / повтор, а не то, что было описано в более ранней статье - упс! Теперь я подозреваю, что Даниэль Вагнер и здесь прав, и проблема в том, что счетчик не увеличивается.]

...