问题标签 [stm]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
108 浏览

concurrency - 原子与参考有何不同?

atom 和 refs 实际有何不同?

我知道原子的声明方式不同,并通过swap!函数更新,而 refsalterdosync. 然而,内部实现似乎非常相似,这让我想知道为什么我会使用一个而不是另一个。

例如,atoms 的文档页面 ( http://clojure.org/atoms ) 指出:

在内部,交换!读取当前值,将函数应用于它,并尝试比较并设置它。由于另一个线程可能在中间时间更改了该值,它可能必须重试,并在自旋循环中这样做。最终效果是该值将始终是原子地将提供的函数应用于当前值的结果。但是,由于该函数可能会被多次调用,所以它必须没有副作用。

所描述的方法听起来与我用于参考的 STM 非常相似。

0 投票
1 回答
420 浏览

clojure - Clojure STM 与原子和代理形式有关系吗?

我正在研究 Clojure 中的并发编程。 http://clojure.org/concurrent_programming

我知道atomrefagent形式用于维护程序状态。

只有ref用于协调更新,因此执行更改时使用dosync宏。

所以很明显,这时候就涉及到了STM引擎。

只是想清楚我有以下疑问,

Clojure STM 是否也与原子和代理形式有关系?还是他们只是利用了 java.util.concurrent.atomic 功能?

0 投票
3 回答
190 浏览

concurrency - 单个原子与多个参考

使用单个 atom 和 hashmap 与多个 ref 表示状态的权衡是什么?

例如:

对比

非常感谢

0 投票
5 回答
492 浏览

multithreading - 停止线程交错输出

下面的程序创建了两个并发运行的线程,每个线程随机休眠一段时间,然后将一行文本打印到标准输出。

输出通常看起来像

您如何确保一次只有一个线程可以写入标准输出?这似乎是 STM 应该擅长的那种事情,但是所有的 STM 事务都必须有STM asome的类型a,而打印到屏幕上的动作有 type IO a,而且似乎没有办法嵌入IOSTM中。

0 投票
1 回答
144 浏览

haskell - 在 GHCi 中查看 TVar 的值

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

我正在尝试在 GHCi REPL 中对此进行测试

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

我试过了

0 投票
2 回答
367 浏览

haskell - 如何将 F# stm 编写为 >>= 管道

有人可以解释如何将此 FSharpx stm 编写为管道吗?

我正在考虑类似haskell的>>=管道。

谢谢!

更新:为了避免混淆,做一点澄清:

我在想应该能够根据 stm.Bind 和 stm.Return 在 F# 中定义 >>= 运算符。我迷路了,我试图自己做到这一点。

UPDATE2:在Thomas 的回答之后,我发布了我认为看起来还不错的更新版本。如果我理解正确,由于缺少类型类,运算符 >>= 没有与 Haskell 相同的功能。

我同意这对于 F# 来说不是惯用的,但它可能是一个很好的练习。

谢谢!

0 投票
1 回答
208 浏览

programming-languages - 唯一性类型代替 STM

一个论坛帖子指出使用唯一性类型而不是 STM。我不明白它在说什么。例如,唯一性类型如何处理 STM 试图处理的多个线程正在更新同一变量的问题?

我查看了维基百科关于唯一性类型线性类型的文章,但仍然不清楚论坛帖子的含义。

0 投票
1 回答
225 浏览

haskell - 使用 orElse 嵌套的 STM 事务中的验证

这个评论页面描述了 GHC 中的许多细节STM,但我想澄清几点。

首先,当父级中访问的变量发生变化时,嵌套事务是否失效?

例如我们在线程中有A

假设在A执行嵌套事务takeTMVar b时,另一个线程B执行putTMVar a ();线程可以A成功完成其嵌套事务,还是无效(这会让我觉得错了)?

我认为我理解但不介意保证的第二点:在重试上述整个顶级事务A并最终阻塞的情况下,当任何,或更改A时将被唤醒是否正确?abc

最后作为奖励,如果我们(或库作者)更改orElse为,上述事务的语义是否会更改infixr

0 投票
1 回答
521 浏览

clojure - 事务中的 deref 可能会触发重试 - ref 状态历史的作用是什么?

“Clojure 编程”(Emerick,O'Reilly)指出:

(...) 如果自当前事务开始后由另一个事务提交了新值,则无法提供截至事务开始时的新值。有用的是,STM 注意到了这个问题,并维护了事务中涉及的 refs 状态的有限历史,其中历史的大小随着每次重试而增加。这增加了 - 在某些时候 - 事务不必再重试的机会,因为虽然 ref 被同时更新,但所需的值仍然存在于历史记录中。

接下来,他们给出了一些代码示例来说明问题。

首先,为了说明读取事务只有在所有写入事务完成后才会成功(因此a = 500):

其次,为了说明该设置:min-history:max-history有助于读取器事务重试(这次a已成功读取较早 - 值为 33):

我确实理解为什么deref读取器事务内部会导致它重试(当某些写入器事务正在提交对 ref 的更改时)。我不明白的是这部分:“这增加了 - 在某些时候 - 事务不必再重试的机会,因为虽然 ref 被同时更新,但所需的值仍然存在于历史记录中”。

什么是“期望值”?在上面的示例中,参考历史如何随时间变化?有人可以向我指出一个解释或一些带有时间线的例子,显示参考历史是如何工作的吗?

0 投票
3 回答
715 浏览

multithreading - 使用带超时的 Tchan

我有一个 TChan 作为线程的输入,它的行为应该是这样的:

如果 sombody 在特定时间内写入 TChan,则应检索内容。如果在指定时间内没有写入任何内容,则应解除阻塞并继续Nothing

我对此的尝试是使用这样的超时功能System.Timeout

这似乎有效,但现在我发现,我有时会丢失数据包(它们被写入通道,但在另一侧没有读取。在日志中我得到这个:

其中“Pushing Recorded Packet”是来自一个线程的写入,“Sending Recorded Packet”是从发送者线程中的 TChan 读取。缺少带有 的行Sending Recorded Packet 2 1439,这表明从 TChan 读取成功。

似乎如果在错误的时间点收到超时,通道就会丢失数据包。我怀疑threadKill里面使用的功能timeout和STM一起玩不好。

这个对吗?有人有另一种不会丢失数据包的解决方案吗?