2012-03-18 35 views
0

在我的應用程序中,有幾個線程修改相同的數據。在「正常」情況下,總是會有一條消息,我發現如果數據量很大,可能會發生其他線程更快並且在loopAction運行之前被刪除messages一個動作中的不可辯駁的模式?

transMit :: Socket -> POSIXTime -> String -> TPSQ -> TMap -> IO() 
transMit s time newmsgs q m = do 
    loopAction <- atomically $ do 
         mT <- readTVar m 
         qT <- readTVar q 
         let mT' = Map.delete key mT 
         let qT' = PSQ.delete key qT 
         writeTVar q (PSQ.insert key time qT') 
         writeTVar m (Map.insert key [newmsgs] mT') 
         return (let Just messages = Map.lookup key mT in sendq s (B.pack $ unwords messages) "192.168.35.84" 4711) 
    loopAction 

我想在這裏的情況下,表達式,如

case (Map.lookup key MT) of 
          Nothing -> return() 
          _ -> something w IO 

,但它並沒有當然的,因爲一個回報的工作()和其他分支返回IO(),等。什麼是我的最好採取解決這個問題?

+4

順便說一句,'do {m < - mm; m}≡join mm',所以你可以寫'join。原子地$ do ...'。 – Vitus 2012-03-18 12:58:15

回答

3

這應該可以解決錯誤類型:

return $ case Map.lookup key mT of 
       Nothing -> return() 
       Just messages -> sendq s (B.pack $ unwords messages) "192.168.35.84" 4711 

這樣兩個分支產生IO(),從而在整體上一個STM (IO())

但我不確定在價值方面發生了什麼。 mT當然不能被不同的線程修改...

+0

是的。爲什麼是這樣?我想從你那裏學到這些。 – 2012-03-18 10:01:37

+1

@JFritsch對不起,我在看到你的評論之前加入了我的答案。我還沒有解釋我的答案的一部分嗎?哪一部分? – dave4420 2012-03-18 10:05:42

+0

謝謝dave4420。 – 2012-03-18 10:54:14

相關問題