【问题标题】:Haskell STM shard TVARHaskell STM 分片 TVAR
【发布时间】:2013-01-05 14:35:38
【问题描述】:

我是 Haskell 和 STM 的新手,我正在尝试理解基本概念。

在一般的 Haskell 和函数式编程中,如果我错了,请纠正我,没有像赋值这样的东西。

我不能写x=3;,我只能用x3生成另一个绑定。

现在谈到 TVar 和线程,如果我有多个线程共享同一个 TVar,如果一个线程更改值,writeTVar,其他线程将看到更改的值,对吗?

如果我有 2 个线程共享同一个 TVar Int var,第一个线程加 1,如果成功,第二个线程会看到更新的值?

谢谢

【问题讨论】:

    标签: haskell stm tvar


    【解决方案1】:

    最好将TVar 考虑为不是变量,而是可以读取和写入的通道。

    纯变量可以被认为是一个纯函数,它总是返回一些值(这个值只绑定一次,就像你的例子一样)。 monad 中的变量/函数有一些“上下文”(这就是 monads 的用途),可能会改变它的值(例如,System.Random 中的 randomIO :: Random a => IO a 可能被认为是“monadic 值”,值,可以在任何电话)。

    TVar 的读写是不纯的显式操作,这就是为什么函数readTVar/writeTVar 被包装到STM monad 中,它们依赖于一些隐藏的上下文,这可能会改变结果(使线程之间可能的值传递)。这会将这些操作限制在 STM monad 中,但只能转义到 IO

    【讨论】:

    • 谢谢你,这澄清了很多:)
    【解决方案2】:

    是的,TVar 是容器,它不会随着内容的变化而变化。所有线程都看到同一个容器,当一个线程更改容器中存储的内容时,当另一个线程查看时,它会找到更改后的值。

    【讨论】:

    • 好的,感谢您的确认,刚开始看起来有点奇怪。
    • 如果可以的话,只是一个额外的小问题:当我使用forkIO 创建线程时,由于返回值是IOThread,因此获得线程计算结果的唯一方法是使线程写入TVar 并从中读取“主”?
    • 不一定是TVar,您也可以使用TChanChanMVarIORef 甚至更多。但原理确实是,如果要和forkIOd线程通信,就需要某种通信变量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2019-06-06
    • 2015-08-01
    相关资源
    最近更新 更多