TChan 写入是否已集成到 Haskell STM 中?

2023-11-21

如果 STM 事务失败并重试,是否会调用writeTChan重新执行,以便最终得到两次写入,或者 STM 仅在事务提交时才实际执行写入?即,这个针对睡觉理发师问题的解决方案是否有效,或者如果交易在enterShop第一次失败?

import Control.Monad
import Control.Concurrent
import Control.Concurrent.STM
import System.Random
import Text.Printf

runBarber :: TChan Int -> TVar Int -> IO ()
runBarber haircutRequestChan seatsLeftVar = forever $ do
  customerId <- atomically $ readTChan haircutRequestChan
  atomically $ do
    seatsLeft <- readTVar seatsLeftVar
    writeTVar seatsLeftVar $ seatsLeft + 1
  putStrLn $ printf "%d started cutting" customerId
  delay <- randomRIO (1,700)
  threadDelay delay
  putStrLn $ printf "%d finished cutting" customerId

enterShop :: TChan Int -> TVar Int -> Int -> IO ()
enterShop haircutRequestChan seatsLeftVar customerId = do
  putStrLn $ printf "%d entering shop" customerId
  hasEmptySeat <- atomically $ do
    seatsLeft <- readTVar seatsLeftVar
    let hasEmptySeat = seatsLeft > 0
    when hasEmptySeat $ do
      writeTVar seatsLeftVar $ seatsLeft - 1
      writeTChan haircutRequestChan customerId
    return hasEmptySeat
  when (not hasEmptySeat) $ do
    putStrLn $ printf "%d turned away" customerId    

main = do
  seatsLeftVar <- newTVarIO 3
  haircutRequestChan <- newTChanIO
  forkIO $ runBarber haircutRequestChan seatsLeftVar

  forM_ [1..20] $ \customerId -> do
    delay <- randomRIO (1,3)
    threadDelay delay
    forkIO $ enterShop haircutRequestChan seatsLeftVar customerId 

UPDATE直到上面的事实之后我才注意到hairRequestChan无论如何,不​​必成为交易的一部分。我可以用普通的Chan并做writeChan in an if陈述after the atomically阻止enterShop。但做出这样的改进就破坏了提出这个问题的全部理由,所以我将其保留在这里。


TChan操作在提交事务时执行,就像其他 STM 操作一样,因此无论重试事务多少次,您始终都会以单次写入结束。否则它们就毫无用处。

为了说服自己,请尝试这个例子:

import Control.Concurrent
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan

main = do
  ch <- atomically newTChan
  forkIO $ reader ch >>= putStrLn
  writer ch

reader = atomically . readTChan
writer ch = atomically $ writeTChan ch "hi!" >> retry

这将抛出一个异常,抱怨事务被无限期地阻止。如果writeTChan如果在事务提交之前发生写入,程序将打印“hi!”在抛出该异常之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TChan 写入是否已集成到 Haskell STM 中? 的相关文章

  • Haskell:对 Num 类型类的使用感到困惑

    我很困惑为什么这有效 f Num a gt a gt a f x x 42 但这并没有 g Num a gt a gt a g x x 4 2 我本来就明白Num包含实现运算符的所有类型 因此 如果42 is an Int and 4 2
  • 为什么 mod 在表达式中给出的结果与在函数调用中给出的结果不同?

    假设有人想要计算函数 f x y x mod 3 y mod 3 mod 2 那么 如果再展开f 1 0 手动 可以得到 1 mod 3 0 mod 3 mod 2 1 然而 如果使用内联函数 结果是 let f x y x mod 3 y
  • Haskell Fibonacci 达到最大指定数?

    我有一个已启动并正在运行的 Haskell 函数 但它做错了事情 它应该输出最多指定最大数量的斐波那契数列 像这样 fibonacciSequence 86 1 1 2 3 5 8 13 21 33 54 我的代码当前输出斐波那契数列中的前
  • 如何只修改记录的一个字段而不完全重写它? [复制]

    这个问题在这里已经有答案了 It s the second time I m tackling this problem And for the second time this is while working with the Stat
  • 使用 Haskell 绘制图表

    是否可以使用 Haskell 绘制一个简单的图表 你们中的任何人都可以告诉我该怎么做吗 该图应至少包含 3 个点 Haskell 图表 https github com timbod7 haskell chart似乎不错 The wiki
  • 由于垃圾收集,Haskell 程序中会出现多长时间的暂停?

    关于我的另一个问题Haskell 集合可以保证每个操作的最坏情况范围 https stackoverflow com q 12393104 1333025 我很好奇 垃圾收集会导致多长时间的暂停 Haskell 是否使用某种增量垃圾收集 以
  • 优化 Haskell 内循环

    仍在 Haskell 中进行 SHA1 实现 我现在已经有了一个有效的实现 这是内部循环 iterateBlock Int gt Word32 gt Word32 gt Word32 gt Word32 gt Word32 gt Word3
  • 与 Functor 不同,Monad 可以改变形状?

    我一直很喜欢以下关于单子相对于函子的力量的直观解释 单子可以改变形状 函子不能 例如 length fmap f 1 2 3 总是等于3 然而 对于单子来说 length 1 2 3 gt gt g往往不等于3 例如 如果g定义为 g Nu
  • 如何与更高级别的类型合作

    玩弄教堂的数字 我遇到了无法指导 GHC 类型检查器处理高阶类型的情况 首先我写了一个版本 没有任何类型签名 module ChurchStripped where zero z z inc n z s s n z s natInteger
  • Haskell 中的内部爆炸模式是否总是强制使用外部构造函数?

    在 Haskell 中 是否存在对于数据类型 LANGUAGE BangPatterns import Control DeepSeq data D D Int 实例 instance NFData D where rnf D 与具有另一个
  • 承诺的反面是什么?

    承诺代表将来可能可用 或无法实现 的值 我正在寻找的是一种数据类型 它表示将来可能变得不可用的可用值 可能是由于错误 Promise a b TransitionFromTo
  • Haskell if-then-else 条件中的“解析输入错误”

    当我尝试编译以下 do 块时 它会抛出错误 输入 conn 上的解析错误 我尝试了许多不同的 if then else 语句配置 但均无济于事 在我添加条件之前 数据库逻辑就起作用了 所以这没有问题 else 中是否有太多行 有没有办法在不
  • seq在haskell中代表什么

    我是 Haskell 的新手 刚刚进入惰性世界编程 我读到seq函数非常特殊 因为它强制使用严格的评估 以便在某些情况下更加有效 但我就是找不到什么seq代表字面意思 也许严格评估Q 它应该提醒您 顺序 或 顺序 因为它允许程序员指定其参数
  • 不理解 Monoid 定义中态射的表示法

    我试图理解什么Monoid是从范畴论的角度来看的 但我对用来描述它的符号有点困惑 这是维基百科 在范畴论中 幺半群范畴 C I 中的幺半群 或幺半群对象 M 是一个对象 M 和两个态射 M M M 称为乘法 I M 称为单位 我的困惑在于态
  • 非单射封闭型族

    我确实有一段人为设计的代码 LANGUAGE DataKinds TypeFamilies data Foo Foo type family Id n Foo a where Id Foo a a data Bar n Foo Bar cl
  • 将List中的相邻元素放入元组中

    给定一个元素列表 xs a b c d z where a b c等是任意值的占位符 我想实现一个功能adjacents a gt a a 产生 adjacentValues a b b c c d y z 在 Haskell 中 递归定义
  • 在 Haskell 中证明“没有腐败”

    我所在的行业对安全要求很高 我们的软件项目一般都会有安全要求 我们必须证明该软件具有高度确定性 通常这些都是负面的 例如 腐败的频率不得超过 1 我要补充的是 这些要求来自统计系统安全要求 损坏的根源之一显然是编码错误 我想使用 Haske
  • 如何给Servant中的所有端点添加前缀?

    我在 Haskell 仆人中有一个 hello world 应用程序 这是其中的一部分 type API my items gt Get JSON MyItem lt gt my items gt Capture id Int gt Get
  • 对 F# 中任意嵌套级别的列表求和

    我正在尝试创建一个 F 函数 它将返回列表的总和int任意嵌套 IE 它将适用于list
  • Haskell:去掉 liftM2 中的括号

    如何去掉标有的括号 而不引入新名称 如果能分成多行就更好了 liftM2 somefunc arg1 get arg2 somefunc arg3 get arg3 您可以使用以下方法删除最后一个 但另一个显然不能在不引入新名称的情况下被删

随机推荐

  • 在 k8s 中使用本地 docker 镜像,无需设置注册表

    我已经根据以下内容设置了单节点 kubernetes官方教程 除了官方文档之外 我还设置了单节点集群 kubectl taint nodes all node role kubernetes io master 残疾人驱逐限制 cat lt
  • Treeview ContainerFromItem 始终返回 null

    我已经阅读了有关此主题的一些主题 但找不到任何可以做我想做的事情 我有一个绑定到一组分层对象的树视图 这些对象中的每一个都代表地图上的一个图标 当用户单击地图上的某个图标时 我想在树视图中选择该项目 将焦点放在它上 然后将其滚动到视图中 地
  • 如何制作可扩展 Flutter 小部件的动画以将其滑出屏幕

    我有两个连续的可扩展按钮占据了整个屏幕宽度 单击左侧按钮时 我希望左侧按钮占据整个屏幕宽度 右侧按钮通过向右滑动到屏幕外而消失 这是我到目前为止所取得的成就 正如您所注意到的 当没有足够的空间来渲染右侧按钮时 它会在最后被压扁 我只是希望它
  • Django Rest Framework 数据库错误异常处理

    有没有办法让 Django Rest Framework 自动响应HTTP 400 STATUS什么时候出现数据库异常 IntegrityError等等 示例 我有一个具有唯一用户名字段的模型 并且我正在尝试使用通用的rest framew
  • 将文件转换为 Base64String 并再次转换回来

    标题说明了一切 我像这样读了 tar gz 存档 将文件分解为字节数组 将这些字节转换为 Base64 字符串 将 Base64 字符串转换回字节数组 将这些字节写回到新的 tar gz 文件中 我可以确认两个文件的大小相同 以下方法返回
  • 强制元素水平对齐

    假设我的 div 中有随机的子元素 其固定高度和宽度设置为 100 以便与布局同步 我必须使用哪种 CSS 来强制子元素水平对齐 并且当 div 的宽度小于内容时 显示滚动条并且不相互重叠 Fiddle http jsfiddle net
  • 如何更改 PostgreSQL 数据库表中列的位置?

    我尝试了以下方法 但没有成功 ALTER TABLE person ALTER COLUMN dob POSITION 37 改变列位置 在 PostgreSQL Wiki 中说道 PostgreSQL 目前定义了列 订单基于attnum的
  • 如何使用 Karma Runner(又名 Testaulous)提供 svg 和固定装置

    在过去的两个小时里 我一直在尝试让 Karma runner 提供 svg 文件和 html 固定装置 但到目前为止还没有成功 根据该线程的第二个答案 将 html 与 testaulousjs 集成时出错我一直在尝试使用served表明我
  • 使用 shell 脚本合并两个属性文件

    如何合并两个属性文件 例如使用 shell 脚本 如果我有两个属性文件 例如 first properties test file anish test version 3 0 second properties test author n
  • 通过单击并拖动来“检查”多个复选框?

    我有一个充满复选框的表格 如下所示 我希望能够按住鼠标并拖动以激活多个复选框 我不知道从哪里开始 我寻找答案 但只找到了另一个线程有人询问如何做 但没有答案 HTML table tbody tr td td tr tbody table
  • 在 JavaFX 2.2 桌面应用程序中嵌入 Google 地图会引发异常并且通常无法执行

    我有一个项目需要在桌面java应用程序中嵌入谷歌地图 经过一番研究后 我发现 Java FX 确实提供了此功能 并继续编写了一个示例应用程序作为 PoC 应用程序运行正常 一切都很好 升级到新的 7u7 java 版本后 我的代码不再像以前
  • 应用程序第一次升级 sqlite 数据库时崩溃

    当第一次更新 sqlite 数据库时 我的应用程序遇到崩溃 重新加载应用程序 从此一切正常 我猜这与 onUpgrade 函数有关 我似乎无法找到问题出在哪里 非常感谢任何建议 提前致谢 数据库助手 public class Databas
  • 如何在 C# 中处理 JSON?

    是否有一个简单 优雅的解析器来处理 C 中的 JSON 实际序列化 反序列化为 C 对象怎么样 JSON Net是一个相当不错的图书馆
  • 如何根据 pandas python 中的特定列合并两个数据框?

    我必须合并两个数据框 df1 company standard tata A1 cts A2 dell A3 df2 company return tata 71 dell 78 cts 27 hcl 23 我必须将两个数据帧统一为一个数据
  • 在对等方关闭的 TCP 套接字上写入

    我有一个客户端 服务器应用程序 其中每一端都通过 TCP 套接字与另一端进行通信 我正确地建立了连接 然后在客户端将任何数据写入套接字之前使服务器崩溃 我看到的是第一个write 尝试 客户端 成功 它返回实际写入的字节数 而以下返回 如我
  • 如何为所有派生类型部分特化类模板?

    我想部分专门化一个我无法更改的现有模板 std tr1 hash 对于基类和所有派生类 原因是我使用了奇怪的重复模板模式来实现多态性 并且哈希函数是在 CRTP 基类中实现的 如果我只想部分专门化 CRTP 基类 那么很简单 我可以编写 n
  • 在多个集合上执行事务时,MongoDB Atlas 出错(代码 8000)

    我正在尝试从 Mongo DB Node JS 驱动程序在 Mongodb Atlas M0 实例上执行事务 如所述here 并且我收到以下错误 code 8000 codeName AtlasError errmsg internal a
  • OpenCV Python:绘制 minAreaRect (旋转矩形未实现)

    是否有任何辅助方法来绘制由返回的旋转矩形cv2 minAreaRect 大概是作为 x1 y1 x2 y2 angle cv2 矩形 不支持角度 由于返回的元组不是 RotatedRect 类 因为它似乎没有在 Python 绑定中实现 所
  • 添加多个 ClusterManager 到 Google 地图

    我正在尝试为 Google Map 使用两个 ClusterManager 但我只能添加一个 clustermanager 及其项目单击事件 googleMap setOnMarkerClickListener mClusterManage
  • TChan 写入是否已集成到 Haskell STM 中?

    如果 STM 事务失败并重试 是否会调用writeTChan重新执行 以便最终得到两次写入 或者 STM 仅在事务提交时才实际执行写入 即 这个针对睡觉理发师问题的解决方案是否有效 或者如果交易在enterShop第一次失败 import