Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 单子问题_Haskell_Concurrency_Monads_Transactional Memory - Fatal编程技术网

Haskell 单子问题

Haskell 单子问题,haskell,concurrency,monads,transactional-memory,Haskell,Concurrency,Monads,Transactional Memory,这只是一个假设的场景来说明我的问题。假设有两个线程,它们之间共享一个TVar。在一个线程中,有一个读取TVar的原子块,需要10秒才能完成。在另一个线程中,是一个原子块,它每秒修改TVar。第一个原子块会完成吗?当然它会一直回到开始,因为日志永远处于不一致的状态 不,可以。这两个线程的交互方式取决于 重试逻辑 例如,假设您有: ten tv = do n <- readTVar tv when (n < 7) retry writeTVar tv 0 -- do so

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

不,可以。这两个线程的交互方式取决于 重试逻辑

例如,假设您有:

ten tv = do
  n <- readTVar tv
  when (n < 7) retry
  writeTVar tv 0
  -- do something that takes about 10 seconds

one tv = do
  modifyTVar tv (+1)
  -- do something that takes about 1 second
ten tv=do

nSTM可以防止死锁,但仍然容易饿死。在病态情况下,1s原子的活动可能总是获得资源

然而,这种变化是非常罕见的——我不相信我在实践中见过


有关语义,请参见第6.5节“进度”。Haskell中的STM仅保证正在运行的事务将成功提交(即没有死锁),但在最坏的情况下,无限事务将阻止其他事务。

正如其他人所说:理论上,没有进展的保证。在实践中,也无法保证取得进展:

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"
import Control.Monad——不需要,但会清理一些东西
导入控制.Monad.STM
导入控制.Concurrent.STM
导入控制。并发
进口温室气体浓度
导入系统.IO
main=do
电视IO()
f tv=永远$do
原子级$do
n IO()
g tv=永远$do
原子级$do

我真的在想最坏的情况。让我们忘记重试一会儿,只考虑两个线程,并考虑STM“十”的执行。它读取TVar,并将该值提交到日志。同时,另一个线程在执行'ten'期间始终更改TVar。因此,在“十”执行结束时,实际TVar中的值与最初在“十”中读取的值不同,迫使“十”重新初始化日志并每次重新执行。正如Yitz所说,这取决于。是的,可以构建一个事务永远无法完成的情况。或者更正式地说,STM不能保证进步。很好的例子。我想用这样的东西进行测试,但我不知道
unsafeiotstm
函数!STM不一定是非阻塞的。