STM单子问题 [英] STM monad problem

查看:259
本文介绍了STM单子问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这只是一个假设的场景来说明我的问题。假设有两个线程和一个TVar在它们之间共享。在一个线程中有一个原子的块,读取TVar,需要10s来完成。在另一个线程是一个原子块,每秒修改TVar。第一个原子阻挡是否会完成?当然,它只会继续回到开始,因为日志永远处于不一致的状态?

This is just a hypothetical scenario to illustrate my question. Suppose that there are two threads and one TVar shared between them. In one thread there is an atomically block that reads the TVar and takes 10s to complete. In another thread is an atomically block that modifies the TVar every second. Will the first atomically block ever complete? Surely it will just keep going back to the beginning, because the log is perpetually in an inconsistent state?

推荐答案

正如其他人所说:理论上不能保证进度。在实践中也不能保证进度:

As others have said: in theory there is no guarantee of progress. In practice there is also no guarantee of progress:

import Control.Monad -- not needed, but cleans some things up
import Control.Monad.STM
import Control.Concurrent.STM
import Control.Concurrent
import GHC.Conc
import System.IO

main = do
    tv <- newTVarIO 0
    forkIO (f tv)
    g tv

f :: TVar Int -> IO ()
f tv = forever $ do
    atomically $ do
            n <- readTVar tv
            writeTVar tv (n + 1)
            unsafeIOToSTM (threadDelay 100000)
    putStr "."
    hFlush stdout

g :: TVar Int -> IO ()
g tv = forever $ do
    atomically $ do
            n <- readTVar tv
            writeTVar tv (n + 1)
            unsafeIOToSTM (threadDelay 1000000)
    putStrLn "Done with long STM"

上面从来没有说过测试。

The above never says "Done with long STM" in my tests.

显然,如果你认为计算仍然有效/相关,那么你会想要

Obviously if you think the computation is still going to be valid/pertinent then you would want to either


  1. 保留原子块,执行昂贵的计算,输入原子块/确认假设有效并更新该值。

  2. 在原子块中记忆结果,所以仍然有效的结果在重试后将不会是一个便宜的查找。

这篇关于STM单子问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆