我想在STM事務中調用一個UDP發送函數,這樣我就可以避免在最終發送值之前避免m'被讀取(並且可以由其他線程更新)的代碼,如下所示:&其中兩個連續的where子句讓我看起來很「無奈」。如何將System.IO.Unsafe與TVars一起使用?
sendRecv s newmsgs q m = do
m' <- atomically $ readTVar m
time <- getPOSIXTime
result <- appendMsg newmsgs key m
when (result > 0) (atomically $ do
mT <- readTVar m
qT <- readTVar q
--let Just messages = Map.lookup key mT in sendq s (B.pack $ unwords messages) "192.168.1.1" 4711
let mT' = Map.delete key mT
qT' = PSQ.delete key qT
writeTVar q (PSQ.insert key time qT')
writeTVar m (Map.insert key [newmsgs] mT'))
when (result > 0) (let Just messages = Map.lookup key m' in sendq s (B.pack $ unwords messages) "192.168.1.1" 4711)
sendq :: Socket -> B.ByteString -> String -> PortNumber -> IO()
sendq s datastring host port = do
hostAddr <- inet_addr host
sendAllTo s datastring (SockAddrInet port hostAddr)
return()
我認爲,通過與newTVarIO
調用TVars和使用import System.IO.Unsafe
我可能最終使用unsafePerformIO
的地方,並從交易中調用我的SendQ函數(即返回IO()
)。
但是,我不知道這個「某處」在哪裏?它是在創建TVar嗎?是不是atomically $ do
?我是否理解unsafePerformIO的適用性錯誤?
+1指出這真的不可能。 – 2012-02-22 22:28:28
有沒有可能將線程a的事務優先於線程b?例如。如果線程a不斷地處理事務並且更頻繁地使用線程b,那麼可能會有什麼「中斷」嗎?我嘗試了一個MVar,其中b可以防止一段時間的運行。但不是很優雅。 – 2012-02-22 23:38:26
@JFritsch MVars和STM並沒有真正的混合。我不知道有什麼辦法可以要求一個線程優先於另一個線程。但是,如果你不活躍,兩條線索最終都會取得進展。 – 2012-02-22 23:44:50