问题标签 [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.
memory - Clojure STM 内存不足
我有一个小程序应该使用 STM 执行并行银行转账,所以我在不同的机器上测试它,2 核和 1 核。在 2 核机器上一切正常,但在 1 核机器上,当我执行 100 万个并行事务时,会抛出 Java Out of Memory 错误。
错误是以下“AWT-EventQueue-0” java.lang.OutOfMemoryError: Java heap space
此外,我有一个相同程序的 Java 同步版本,它可以工作,即使速度较慢,它也可以达到一百万笔交易。
我可以做些什么来让我的 Clojure 应用程序在 1 核机器上工作?恐怕垃圾收集器无法处理这么多 Refs ......你怎么看?
非常感谢你的帮助!
更新:
它现在可以工作了,我做到了java -Xmx1000m -jar myprog.jar
并且工作得很好!
我不知道可以增加 JVM 的堆大小,而这正是我的问题。非常感谢“sw1nn”的精彩评论;)
haskell - Haskell TVar 的容器
我有一个游戏服务器,它使用 forkIO 为每个客户端生成一个线程。例如,我想与所有客户共享客户列表和怪物列表。
我的第一个想法是为包含两个列表的数据类型创建一个 TVar 容器,但假设两个线程同时更改客户端和怪物,如果我理解该部分正确,这将回滚其中一个。这将是不必要的回滚。
第二个想法是制作列表 TVar,然后将它们作为参数传递,但如果要添加更多列表,我宁愿将它们放在容器中以保持代码清洁和易于管理。
有没有办法在一个容器中传递几个 TVar 或者我是否过度考虑了第一个想法?
haskell - Haskell:自动更新两个或多个 TVar。可能的?
TVar
一个事务可以以原子方式更新两个不同的 s 吗?即我可以用大量的 s 组成数据结构TVar
来减少争用吗?如果是这样,你能举个例子吗?
haskell - Haskell:TVar:防止饥饿
我正在考虑使用 TVar 在 Web 应用程序中存储一些状态(可以在重新启动时重新创建)。但是,我担心 TVar 的争用方面。似乎频繁的短时间运行的事务可以通过不断地中断较长的事务来饿死它们。此外,随着更多运行时间较长的事务不断重启,这将增加 CPU 的负载,从而进一步增加这些事务的长度。最终我觉得这可能会导致服务器完全没有响应。
考虑到这一点,我有以下问题:
(1) TVar(或其他数据类型)可以使用锁,而不是同时尝试/重试。
(2)TVar(或其他数据类型)能否有一些不同的争用机制,即“让事务在运行另一个事务之前运行一秒钟”,或者至少有一些保证事务最终会完成(即防止对运行时间更长的事务)。
haskell - 没有死锁或资源匮乏的并发通用数据结构
我最近问了一些关于 的问题TVar
,但我仍然对活锁感到担忧。
于是我想到了这个结构:
- 每个事务都有一个唯一的优先级(可能按创建顺序分配)。
- 事务尝试获取它们访问的数据的读/写锁。自然,同时读取是可以的,但是一个写入锁会排除所有其他锁(读取和写入)。
- 假设事务 A 比事务 B 具有更高的优先级。如果 A 持有锁,B 等待,但如果 B 持有锁并且 A 想要它,则 B 从锁中启动,A 获得它,然后事务 B 重新启动(如 with
TVar
)。然而,B 保持其当前的重试优先级。 - 当一个锁被释放并且有事务在等待时,它会转到最高优先级的事务,其余的继续等待。
我相信这个系统可以防止死锁,但也可以防止饥饿(不像TVar
)。我想知道是否有人实施了这样的系统,因为它似乎相当明显,我不想重新发明轮子。
当然,这种方法可以很容易地扩展为允许用户指定优先级。
Priority 可以是 pair (user_supplied_prio, auto_increment)
,具有user_supplied_prio
优先权,但同等优先级的任务按 FIFO 顺序解决。
评论/解决方案:
实际上,当我想到它时,我所描述的已经存在于 Haskell 中,只需使用一个IORef
包裹所有数据的方法,并且仅使用atomicModifyIORef
. 这atomicModifyIORef
将确保按顺序应用事务。然而,有人可能会认为这意味着数据结构是顺序的(即实际上仅限于一个线程),但由于惰性,它实际上是并行的。
为了解释这一点,考虑一个昂贵的函数f
。我们将把它应用到Data.Map
键为“foo”的数据上。
这替换(foo -> x)
为(foo -> future(f x))
. 该线程将继续解决(f x)
实际情况,但同时我们可以将 g 应用于“bar”。由于将g应用于“bar”不需要“foo”的结果,我们可以同时解决这个问题。
没有死锁,没有饥饿,最终所有事务都将被处理(大致按照它们被接收的顺序)。
clojure - STM 事务中的 refs 真的是一致的吗?
我在clojure.org/refs上读到
从事务的起点(它的“读取点”)开始,所有对 Refs 的读取都将看到“Ref world”的一致快照。事务将看到它所做的任何更改。这称为交易中价值。
在 wikipedia上还有一个指向Snapshot Isolation的链接,这意味着一旦事务开始,读取任意数量的 ref 将彼此一致。
我做了一个测试用例...
输出是:
r1 = 3
而不是的值r1 = 0
表明,在deref-delay-deref
ref1 的 deref 中,在三个事务发生后sleep
选择 r1 的值。delay-then-inc-ref
请注意,我知道ensure
要防止在特定事务期间其他事务对 refs 进行更新,但我认为这不适用于此处。ref1
只要我看到与我的交易开始一致的值,我不在乎是否发生变化。
这种行为如何符合上述参考文档?
compiler-construction - 寻找多语言编译器或优化器(c、c++、java)
简而言之,我正在寻找一种方法来编辑开源编译器或优化器,以将传统的锁实现更改为软件跨国内存事务。我有三种目标语言,C、C++ 和 Java。一个想法可能是使用 GCC,因为它现在支持 stm。问题是,我想不出一种方法来实现对 GCJ 转储的 java 字节码的这些更改。llvm 也会出现同样的问题。
tldr; 试图找到像 gcc 或 llvm 这样的编译器或优化器,我可以很容易地破解源代码或源代码的中间表示。
transactions - 关于STM实现的问题
我已经阅读了两个完全不同的关于 STM 是如何实现的说明。也许两者都是有效的,或者一个是错误的,我希望有人能阐明。
采取 1(维基百科):允许所有线程修改共享内存,但事务中的每次读取和写入都会被记录。在事务结束时,系统检查其他线程是否没有同时对内存进行更改。如果未进行任何更改,则提交事务。否则,重新启动事务。
- 问:如果这是一个有效的实现,那么允许两个线程在同一个事务中执行似乎是没有用的。他们将读取彼此的写入,并且交易块内的计算将是错误的。
取2(找不到源):当程序进入事务时,它会获取其中包含的所有变量的副本,并且可以对它们进行访问。在事务结束时,系统尝试用副本更新主控。如果自第一次复制后 master 没有更改,则提交事务。否则,重新启动事务。
另外,当两个线程同时进入同一个事务时会发生什么?这不会导致某种竞争条件吗?由于两者都试图修改相同的共享内存,因此两者都需要重新启动并且问题会无限期地继续下去,除非系统介入并告诉一个线程对其进行冷却(有点像锁=)我确定我是这里缺少一个概念。
concurrency - 是否应该在事务中读取多个 Clojure 引用以保持一致性?
这是一个理论问题,我希望更好地理解 Clojure 的并发性。
假设我正在写 boids。假设每个 boid 是一个单独的绿色线程,它在表示世界网格的向量或 refs 中改变位置。想想希基的蚁群。
现在,Clojure.org 上的文档指出“所有对 Refs 的读取都将看到从事务起点(它的‘读取点’)开始的‘参考世界’的一致快照。”
这是否意味着我只能通过读取事务中的引用向量(即在 dosync 上下文中)来获得模拟的一致快照,例如绘制它?
谢谢!