这个clojure解决方案是否有睡眠理发师的错误?(Is there a bug in this clojure solution to sleeping barber?)

编程入门 行业动态 更新时间:2024-10-28 02:21:53
这个clojure解决方案是否有睡眠理发师的错误?(Is there a bug in this clojure solution to sleeping barber?)

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

我对enter-the-shop的dosync块感到好奇。 我的理解是这是一个交易,因此empty-seats将因STM而保持一致。 但是,如果重试事务,是否有可能多次调用send-off ? 如果没有,为什么,如果是,如何解决它?

UPDATE

虽然接受的答案仍然是正确的,但我刚注意到的一件事是可以进行优化 - 没有理由在交易中调用send-off 。 一旦您拥有交易的返回值,就可以发送它,如下所示:

(if (dosync (when (pos? @empty-seats) (alter empty-seats dec))) (send-off barber cut-hair n) (debug "(s) turning away customer" n))

有趣的是,我在处理Haskell等效时想出了这一点,这迫使你在STM内部和STM外部使用不同类型的“代理”。 上面的原始解决方案不会编译,因为它们必须既可以在事务中,也可以在任何事务之外。 (我的第一反应是将它们都放在交易中,直到我意识到不需要这个并且它们都可以被提取出来)。

我认为修改后的事务应该是优越的,因为它更快地关闭事务,从事务中删除变量,我认为更容易阅读(甚至不想知道它被发送两次的可能性 - 这实际上是这整个问题没什么问题)尽管如此,我还是会留下任何需要知道STM和代理如何互动的人。

This is presented as a solution to the sleeping barber problem. (Attributed to CGrand, but I found the reference here)

I'm curious about the dosync block in enter-the-shop. My understanding is that this is a transaction, and so empty-seats will remain consistent because of STM. However, isn't there the possibility of send-off being called multiple times if the transaction gets retried? If not, why, and if so, how would one resolve it?

UPDATE

While the accepted answer is still correct, one thing I just noticed is there's an optimization that could be made--there's no reason to call send-off inside the transaction. It can be sent afterwards once you have the return value of the transaction, as follows:

(if (dosync (when (pos? @empty-seats) (alter empty-seats dec))) (send-off barber cut-hair n) (debug "(s) turning away customer" n))

Interestingly I figured this out while working on the Haskell equivalent, which forces you to use different types for "agents" inside STM and outside STM. The original solution above wouldn't compile, as they had to be either both in a transaction or both outside any transaction. (My first reaction was to put them both inside the transaction, until I realized there was no need for this and they could both be extracted).

I think the modified transaction should be superior in that it closes the transaction faster, removes a variable from the transaction, and I think is easier to read (there's no need to even wonder about the possibility of it being sent twice--which actually makes this whole question moot) Still, I'll leave the question up anyway for anyone else who needs to know about how STM and agents interact.

最满意答案

在代理商上引用clojure.org页面 :

代理与STM集成 - 在事务中进行的任何调度都会一直保留,直到它提交为止,如果重试或中止则会丢弃。

因此,当(/ if)STM事务成功提交时, send-off只会运行一次。

Quoting the clojure.org page on agents:

Agents are integrated with the STM - any dispatches made in a transaction are held until it commits, and are discarded if it is retried or aborted.

So the send-off will only get run once, when(/if) the STM transaction is successfully committed.

更多推荐

本文发布于:2023-08-03 23:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1405223.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:理发师   睡眠   解决方案   错误   clojure

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!