标签: tvar

Haskell代码散落着TVar操作和函数带来许多争论:代码味道?

我正在Haskell中编写MUD服务器(MUD =多用户地牢:基本上是一个多用户文本冒险/角色扮演游戏).游戏世界数据/状态以大约15种不同的IntMaps表示.我的monad变换器堆栈看起来像这样:ReaderT MudData IO,其中MudData类型是包含IntMaps 的记录类型,每个都在自己的TVar(我使用STM进行并发):

data MudData = MudData { _armorTblTVar    :: TVar (IntMap Armor)
                       , _clothingTblTVar :: TVar (IntMap Clothing)
                       , _coinsTblTVar    :: TVar (IntMap Coins)
Run Code Online (Sandbox Code Playgroud)

...等等.(我正在使用镜头,因此是下划线.)

有些功能需要某些功能IntMap,而其他功能需要其他功能.因此,每个IntMap都有自己的TVar粒度.

但是,我的代码中出现了一种模式.在处理播放器命令的函数中,我需要TVar在STM monad中读取(有时稍后写入)我的s.因此,这些函数最终在其where块中定义了STM帮助器.这些STM助手通常readTVar在其中有相当多的操作,因为大多数命令需要访问少数几个IntMaps.此外,给定命令的函数可以调用许多纯辅助函数,这些函数也需要一些或全部IntMaps.因此,这些纯辅助函数有时会占用大量参数(有时超过10).

所以,我的代码变得"乱七八糟",有很多带有大量参数的readTVar表达式和函数.以下是我的问题:这是代码味道吗?我错过了一些可以使我的代码更优雅的抽象吗?有没有更理想的方法来构建我的数据/代码?

谢谢!

haskell stm tvar

14
推荐指数
2
解决办法
614
查看次数

哈斯克尔:TVar:orElse

orElse由于另一个事务写入TVar已读取的事务,或者仅在retry显式调用时,是否在重试事务时调用了"else"部分?

concurrency haskell ghc stm tvar

12
推荐指数
1
解决办法
732
查看次数

哈斯克尔:TVar:预防饥饿

我正在考虑使用TVar在Web应用程序中存储某些状态(可以在重新启动时重新创建).然而,TVar的争论方面关注我.似乎频繁的短期交易可以通过不断地中断它们来匮乏更长的交易.此外,随着更长时间运行的事务不断重启,这会增加CPU的负载,趋向于进一步增加这些事务的长度.最终我觉得这可能导致服务器完全没有响应.

考虑到这一点,我有以下问题:

(1)TVar(或其他数据类型)可以使用锁,而不是同时尝试/重试.

(2)可以的TVar(或其它数据类型)有一些不同的竞争机制,即"让交易运行另一个事务前一秒钟跑",或至少一些保证交易将最终完成(即竞争算法,以防止饥饿的更长时间的交易).

concurrency haskell ghc stm tvar

7
推荐指数
2
解决办法
696
查看次数

Haskell:TVar是如何工作的?

TVar如何运作?从我所看到的,它尝试在收到它们后立即运行所有事务,但是,事务完成使其他当前运行的事务无效,然后必须重新启动.这是TVar的工作原理吗?

如果是这种情况,如果每100ms发生1ms长的事务,这是否意味着需要200ms处理的事务永远不会完成?

concurrency haskell tvar

6
推荐指数
2
解决办法
723
查看次数

看GHCi中TVar的价值

通过Simon Peyton Jones并发示例,我有以下代码:

import Control.Concurrent.STM
import Control.Concurrent.STM.TVar

deposit account amount = do
    bal <- readTVar account
    writeTVar account (bal+amount)
Run Code Online (Sandbox Code Playgroud)

我试图在GHCi REPL中测试这个

*Main> checking <- atomically $ newTVar 100
*Main> atomically $ deposit checking 10
Run Code Online (Sandbox Code Playgroud)

如何验证我的支票余额是110美元?

我试过了

*Main> checking
*Main> readTVar checking
*Main> balance <- readTVar checking
Run Code Online (Sandbox Code Playgroud)

haskell ghci stm tvar

3
推荐指数
1
解决办法
137
查看次数

Haskell:原子地更新两个或更多TVar.可能?

一个事务可以TVar以原子方式更新两个不同的s吗?即,我可以从许多TVars 组成数据结构,以减少争用?如果是这样,你能提供一个例子吗?

concurrency haskell stm tvar

3
推荐指数
2
解决办法
742
查看次数

TVar 构造函数?我找不到 TVar

我是 Haskell 和 stm 的新手,我想制作一个简单的 rwlock。首先,我创建了 4 个主要函数(wlock、wunlock、rlock、runlock),需要 2 个 TVar 整数:读取线程和写入线程的数量。

此时我无法按预期使用它。我尝试这样编译

v1 <- atomically(newTVar 0);
v2 <- atomically(newTVar 0);
wlock v1 v2 -- wlock :: TVar Integer -> TVar Integer -> IO ()
Run Code Online (Sandbox Code Playgroud)

这当然很丑陋,但它有效(不知道为什么,因为原子地返回IO (TVar a)而不是TVar a

我想要的是:

我试图通过隐藏价值观来让它变得更好。我在某处读到单子可能是可行的方法,但我还没有研究它们。相反,我尝试创建一个新类型的 Rwlock 作为

data Rwlock = Rwlock {  readCant :: TVar Integer 
    ,writeCant :: TVar Integer
}
Run Code Online (Sandbox Code Playgroud)

和一个构造函数,所以我可以做这样的事情:

import Rwlock

do{
    a = rwconst;
    forkIO(reader a);
    forkIO(writer a);
}
Run Code Online (Sandbox Code Playgroud)

rlock a读者和作者都会打电话的地方wlock a

问题: …

haskell stm tvar

-1
推荐指数
1
解决办法
159
查看次数

标签 统计

haskell ×7

tvar ×7

stm ×6

concurrency ×4

ghc ×2

ghci ×1