问题标签 [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 投票
1 回答
175 浏览

haskell - 测量 Tchan 长度

我需要在 STM 中存储一些值的缓冲区。编写器线程需要监视缓冲区的大小。我开始使用TChan来实现这个东西,但后来我发现 API 没有提供测量通道长度的方法。作为一个固执的人,我自己实现了这个东西:

现在一切正常,但我想知道在标准库中没有实现这样一个微不足道的事情的原因是什么,以及解决这个问题的首选方法是什么。我意识到这个算法至少有 O(n) 复杂度,但这不可能是原因,对吧?

0 投票
2 回答
604 浏览

haskell - 读取 Tchan 会导致阻塞或轮询吗?

首先,一些背景。我想要一个队列,我想以两种不同模式之一操作。在第一种模式下,如果队列中存在一个元素,我希望能够检索一个元素,但如果没有元素,则不阻塞。在第二种模式下,我希望能够阻塞直到队列有一个元素。(我知道我可以为每种模式使用专门的机制,但我想排除一些通用代码,因此如果我可以对两种操作模式使用相同的机制,那将是最简单的。)

我可以使用Chan,但根据文档,我不应该使用isEmptyChan它,因为由于可能出现死锁,它已被弃用。这给我留下了TChan. 该tryReadTChan函数为我提供了我想要的第一种模式(即我可以检查元素是否存在而不阻塞),但我不确定究竟是什么readTChan。我的心智模型是,该atomically块将不断重试,直到通道中出现一个元素,这意味着它会忙于循环浪费 CPU 周期;这与readChan(即非 STM 版本)不同,后者(如果我理解正确的话)实际上会阻塞线程的执行,直到元素可用,因为运行时线程调度程序可以理解 MVar。

TChan就像这样,Chan如果我使用readTChan运行时足够聪明,不会在值可用之前调度调用线程?还是会浪费大量 CPU 周期不断轮询一个值到达?

0 投票
2 回答
7104 浏览

haskell - 何时/为什么在 TVar 上使用 MVar

我发现 TVar 很容易使用,尽管 MVar 看起来更简单一些,而 TVar 更有特色。

所以我的问题很简单,我想去 MVar 而不是 TVar 的条件是什么?我想任何时候我不需要事务更新我都可以使用 MVar,但这对我有什么好处?

0 投票
0 回答
74 浏览

type-safety - deuce STM 类型安全吗?

我已经为pi calculus编写了一个JAVA库,它利用Deuce STM来管理并发进程。 我进一步希望证明我的库的类型安全。 Deuce STM 库类型安全吗?如果是,将不胜感激一些相同的链接。

0 投票
1 回答
2612 浏览

clojure - Clojure:原子和参考的惯用用法?

我正在编写一些 Clojure 代码,它将引用映射并增加映射中的键值对。我认为我正确使用了 ref,但我不确定 atom。我需要使用swap吗!更地道?我是 STM 和 Clojure 的新手,这看起来是线程安全的/理智的吗?我错过了什么?

印刷

0 投票
1 回答
200 浏览

clojure - Clojure:为什么 Ref 在 Assoc 上丢失

我正在更新 Clojure 中地图参考中的计数器。

但是,看起来 alter value inc 语句正在丢失引用:

哪个打印:

在这种情况下,如何在更新参考时保持相同的参考?

0 投票
2 回答
1177 浏览

concurrency - Clojure Refs/do-sync 是否等同于 java“同步”块?

我试图说服自己,clojure 确实比 java 更容易进行并发编程。

但我觉得 Clojure Refs/do-sync 与 java“同步”块几乎完全一样。然后我读了这个线程:Clojure STM (dosync) x Java 同步块

--- 我正在重新启动一个新线程,因为如果我在旧线程中发表评论,由于年龄较大,响应可能不高。

Michał Marczyk 在该线程中的第一条评论声称不同之处在于 java 同步块使用锁,而 Clojure 使用事务。我认为这种说法并没有触及问题的本质:在底层,事务仍然是通过锁来实现的。所以“java 使用锁”并不是 Clojure 更好的原因。

我认为真正的好处是 Clojure 事务自动管理锁,就像 DB 事务一样。这样,获取锁的顺序和执行事务的顺序由事务管理器决定,程序员不需要关心这些,而在java世界中,程序员必须显式选择使用哪个锁同步块,这会导致可能的死锁。例如,事务管理器可以使用两阶段锁定来避免死锁。

以上有意义吗?

谢谢杨

0 投票
2 回答
340 浏览

multithreading - Canonical Way to Ensure Only One Instance of a Service Is Running / Starting / Stopping in Clojure?

I'm writing a stateful server in Clojure backed by Neo4j that can serve socket requests, like HTTP. Which means, of course, that I need to be able to start and stop socket servers from within this server. Design-wise, I would want to be able to declare a "service" within this server and start and stop it.

What I'm trying to wrap my mind around in Clojure is how to ensure that starting and stopping these services is thread-safe. This server I'm writing will have NREPL embedded inside it and process incoming requests in a parallel way. Some of these requests will be administrative: start service X, stop service Y. Which opens up the possibility that two start requests come in at the same time.

  1. Starting should synchronously check a "running" flag and a "starting" flag and fail if either are set. In the same transaction, the "starting" flag should be set.
  2. After the "starting" flag is set, the transaction closes. That makes the "starting" flag visible to other transactions.
  3. Then the (start) function actually starts the service.
  4. If (start) succeeds, the "running" and "starting" flags are synchronously set.
  5. If (start) fails, the "starting" flag is set and the exception is returned.

Stopping needs the same thing, checking a "running" flag and checking and setting it's own "stopping" flag.

I'm trying to reason through all possible combinations of (start) and (stop).

Have I missed anything?

Is there a library for this already? If not, what should a library like this look like? I'll open source it and put it on Github.

Edit:

This is what I have so far. There's a hole I can see though. What am I missing?

In the try block, I log, then call .shutdown, then log again. If the first log fails (I/O exceptions can happen), then (:stopping db-) is set to false, which unblocks it and is fine. .shutdown is a void function from Neo4j, so I don't have to evaluate a return value. If it fails, (:stopping db-) is set to false, so that's fine too. Then I set the (:ref db-) to nil. What if that fails? (:stopping db-) is set to false, but the (:ref db-) is left hanging. So that's a hole. Same case with the second log call. What am I missing?

Would this be better if I just used Clojure's locking primitives instead of a ref dance?

0 投票
1 回答
2322 浏览

networking - 1个处理管道,2个同类型IO源

在我GHC Haskell使用 stm、network-conduit 和管道的应用程序中,每个套接字都有一个链,它使用runTCPServer. Strands 可以通过使用广播 TChan 与其他 strands 进行通信。

这展示了我想如何设置管道“链”:

在此处输入图像描述

所以,我们这里有两个源(每个都绑定到辅助管道),它们产生一个Packet对象,该对象encoder将接受并变成ByteString,然后发出套接字。我在两个输入的有效融合(性能是一个问题)方面遇到了很大的困难。

如果有人能指出我正确的方向,我将不胜感激。


由于我不尝试就发布这个问题是不礼貌的,所以我将把我之前尝试过的内容放在这里;

我已经编写/挑选了一个函数,该函数(阻塞)从 TMChan(可关闭通道)产生 Source;

同样,将 Chan 转换为 sink 的函数;

那么mergeSources 就很简单了;fork 2 个线程(我真的不想这样做,但到底是什么),可以将他们的新项目放入一个列表中,然后我会生成一个列表;

虽然我成功地对这些函数进行了类型检查,但我没有成功地利用这些函数进行类型检查;

无论如何,我认为这种方法存在缺陷——有许多中间列表和转换。这对性能不利。寻求指导。


PS。据我所知,这不是重复的;将具有多个输入的管道融合在一起,因为在我的情况下,两个源都产生相同的类型,我不在乎从哪个源产生Packet对象,只要我不等待一个而另一个有准备使用的对象。

聚苯乙烯。对于示例代码中 Lens 的使用(以及知识要求),我深表歉意。

0 投票
1 回答
256 浏览

clojure - 这个 clojure 睡眠理发师解决方案中是否存在错误?

这是作为睡眠理发师问题的解决方案提出的。(归因于CGrand,但我在这里找到了参考)

从cgrand被拉出来

我很dosync好奇enter-the-shop. 我的理解是,这是一个交易,因此empty-seats会因为 STM 而保持一致。但是,如果事务被重试,是不是有可能send-off被多次调用?如果不是,为什么,如果是,如何解决?

更新

虽然接受的答案仍然是正确的,但我刚刚注意到的一件事是可以进行优化——没有理由send-off在事务内部调用。一旦你有了交易的返回值,就可以事后发送,如下:

有趣的是,我在处理Haskell 等效项时发现了这一点,这迫使您在 STM 内部和 STM 外部使用不同类型的“代理”。上面的原始解决方案无法编译,因为它们必须要么都在事务中,要么都在任何事务之外。(我的第一反应是将它们都放入事务中,直到我意识到没有必要这样做并且它们都可以被提取)。

我认为修改后的事务应该更好,因为它可以更快地关闭事务,从事务中删除一个变量,并且我认为更容易阅读(甚至不需要怀疑它被发送两次的可能性——这实际上使得这整个问题没有实际意义)不过,无论如何,我还是把这个问题留给任何需要了解 STM 和代理如何交互的人。