问题标签 [ioref]

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 投票
3 回答
1057 浏览

haskell - 共享 IORef 时,只要我使用 atomicModifyIORef 编写,使用 readIORef 读取是否安全?

IORef如果我在多个线程之间共享一个,并使用atomicModifyIORef它来写入:

用普通的 old 读取值是否安全readIORef?或者修改后是否有机会readIORef在另一个线程中返回旧值atomicModifyIORef

我认为这就是文档所暗示的:

atomicModifyIORef 充当重新排序的障碍。多个 atomicModifyIORef 操作以严格的程序顺序发生。永远不会观察到 atomicModifyIORef 发生在任何更早(按程序顺序)的 IORef 操作之前,或在任何以后的 IORef 操作之后。

我只是想确定一下。

0 投票
1 回答
400 浏览

haskell - 共享可变状态:何时使用 IORefs

我有一个写入 Map 和 PSQ 的主线程。在 Map 和 PSQ 中,我使用相同的键,因此通过查看 PSQ,可以找到具有最小优先级的条目,复杂度为 O(1),并映射到 Map 中的值。

现在,虽然我的主线程在需要时添加/修改了 Map 和 PSQ,但我有第二个线程不断(forever $ do)查看 PSQ 以确定最旧的密钥何时是 N 毫秒前,然后应该刷新它。

为此,两个线程都需要查看相同的可变数据。这里保持状态的最佳方法是什么?这会是 IOREfs 的情况吗?还有什么可能的方法来解决这个问题?

“一些”预阿尔法代码在这里:

0 投票
3 回答
1232 浏览

haskell - Haskell并发使用简单的IORef?

我一直在问一些关于 Haskell 并发的问题,特别TVarTVar.

相反,我提出了这个解决方案。

(1) 将程序中的所有共享数据包装在一个数据结构中,并将其包装在一个IORef. (2) 只需使用atomicModifyIORef.

我相信这可以防止死锁和活锁(而 TVar 只能防止前者)。此外,因为atomicModifyIORef只是将另一个 thunk 链接到一个链中(这是几个指针操作),所以这不是瓶颈。对数据的所有实际操作都可以并行完成,只要它们不相互依赖即可。Haskell 运行时系统会解决这个问题。

然而我觉得这太简单了。有没有我错过的“陷阱”?

0 投票
1 回答
240 浏览

haskell - Haskell:尝试并行`atomicModifyIORef`实现

据我了解,对IORefs 的修改非常快,它们所涉及的只是更新一个 thunk 指针。当然,读者(即想要在他们的网页上看到价值的人)将需要花时间来评估这些 thunk(如果作者没有回读结果,这可能会增加)。

我认为最好开始IORef并行地实际评估修改 thunk,因为在许多情况下,它们可能无论如何都必须在某个时候进行评估(显然,这将破坏无限的数据结构)。

因此,我编写了以下函数,其签名类似于atomicModifyIORef

这似乎有效(测试代码here)。我在这里做错了什么吗?还是有更好的方法来做到这一点?


编辑:第二次尝试

受以下卡尔回答的启发。我们实际上存储force newdataIORef. 这和反正是一样newdata的,但是显示了我们想要force newdata稍后保留的运行时,所以它不会垃圾收集火花。

0 投票
2 回答
957 浏览

performance - Haskell:并发数据结构指南

我一直在尝试理解并发,并且一直在尝试找出更好的方法,一个大IORef锁或多个TVars。我已经得出以下指导方针,我们将不胜感激,关于这些是否大致正确或我是否错过了重点。


让我们假设我们的并发数据结构是一个映射m,像 一样访问m[i]。还可以说我们有两个函数,f_easy并且f_hard. f_easy速度很快,需要f_hard很长时间。我们将假设 的参数f_easy/f_hard是 的元素m

(1) 如果您的交易大致如下所示m[f_easy(...)] = f_hard(...),请使用IORefwith atomicModifyIORef。懒惰将确保m它只被锁定很短的时间,因为它是用一个 thunk 更新的。计算索引有效地锁定了结构(因为有些东西会被更新,但我们还不知道是什么),但是一旦知道那个元素是什么,整个结构上的 thunk 就会移动到仅在那个特定元素上的 thunk ,然后只有那个特定的元素被“锁定”。

(2) 如果你的交易看起来大致是这样m[f_hard(...)] = f_easy(...)的,并且不要冲突太多,使用很多TVars。在这种情况下使用 anIORef将有效地使应用程序成为单线程,因为您不能同时计算两个索引(因为整个结构上会有一个未解决的 thunk)。TVars 让你同时计算出两个索引,但是,不利的是,如果两个并发事务都访问同一个元素,并且其中一个是写入,则必须废弃一个事务,这会浪费时间(本来可以在别处使用)。如果这种情况经常发生,你可能会更好地使用来自 (通过黑洞)的锁IORef,但如果它不经常发生,你将获得更好的TVars 并行性。

基本上在情况(2)中,IORef您可能会获得 100% 的效率(没有浪费的工作)但只使用 1.1 个线程,但TVar如果您的冲突数量较少,您可能会获得 80% 的效率但使用 10 个线程,所以您仍然结束即使浪费了工作,速度也提高了 7 倍。

0 投票
1 回答
899 浏览

haskell - 在纯代码中避免 IORef

我注意到Data.UnionFind使用 IO monad 通过 IORefs 提供指针。我想每个人在以纯代码在本地使用它时都会愉快地调用unsafePerformIO它,因为数据结构很好理解,但是..

这种数据结构是否有规范的清洁方法?也许是 IO 的包装器,它通过禁止大多数 IO 操作使不可避免unsafePerformIO的不安全“看起来”变得不那么安全?

0 投票
2 回答
626 浏览

haskell - 什么haskell数据结构来存储可变树

我正在考虑用haskell编写一个浏览器。中央数据结构将是表示文档的可变树。除了使用完全由 iorefs 组成的树之外,还有更好的解决方案吗?

我希望避免这样的事情:(data DomNode = DomNode TagName NodeProperties (IORef DomNode) [IORef DomNode]标签,属性,父母,孩子)

问题是 javascript 可以保留树中节点的引用,它可以改变(添加子节点、修改属性)它引用的任何节点,以及遍历它的父节点。

编辑:

我意识到您需要以某种方式使用可变状态 - 因为您可以保留对从树中删除或在树中移动的节点的引用。如果你通过基于树结构的东西引用了元素,那么这个引用将是无效的。

0 投票
2 回答
699 浏览

haskell - StateT 与 ReaderT IORef 的异常处理

通过坚持 an 来通过异常维护状态似乎IORef比尝试使用 State Monad 容易得多。下面我们有 2 个替代的状态单子。一种用途StateT,另一种ReaderT IORef。可以轻松地在ReaderT IORef最后一个已知状态上运行最终处理程序。

那么在 main 函数结束时,即使抛出异常,我如何运行一个最终处理程序,它可以访问 State Monad 的最后一个现有状态?或者是ReaderT IORef最佳选择还是有更好的选择?

0 投票
1 回答
271 浏览

haskell - 为什么我不能将值写入 IORef 但可以读取它

在 haskell 中,我需要一个全局变量,所以我选择使用 IORef 插槽,这是我的计划:

我的计划是当执行器评估“调用”节点时,它将参数保存到插槽中。然后,当评估“ARGs”节点时,将读取该备忘录槽。

但无论我做什么,我只能读取 9999 但不能将新值写入该插槽。

即使我尝试过:

它仍然会导致备忘录 = 9999。为什么?

0 投票
2 回答
3092 浏览

haskell - 何时使用 STRef 或 IORef?

STRef 和 IORef 之间到底有什么区别,我什么时候使用它们?据我所知,它们都是可变状态,那么它们存在的意义何在?