STMトランザクション内でUDP send関数を呼び出して、値が最終的に送信される前にm 'が読み取られ、他のスレッドによって更新される可能性のあるコードを避けることができます。& where where where where clauses私をかなり無力に見せてください。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
を使用することができ、トランザクション内から(IO()
を返します)私のSENDQ関数を呼び出すと思いました。
しかし、この「どこか」がどこにあるのかわかりません。それはTVarの創作時ですか?それはatomically $ do
の代わりですか? unsafePerformIOの適用性が間違っているという意味を理解していますか?
+1これは実際には不可能であることを指摘しています。 –
スレッドbのスレッドaのトランザクションに優先順位を付ける可能性はありますか?例えば。スレッドaが常にトランザクションとスレッドbをより頻繁に持っていない場合、bの「割り込み」を行うことができますか?私はMVarを試して、bがしばらく実行されないようにすることができました。しかしエレガントではなかった。 –
@JFritsch MVarsとSTMは実際には混在しません。あるスレッドが別のスレッドよりも優先順位を付けるように求める方法はわかりません。しかし、ライブロックしていない場合、両方のスレッドが最終的に進歩するはずです。 –