gpt4 book ai didi

concurrency - 在 Clojure 中是否有可能使用代理导致死锁(或其他坏情况)?

转载 作者:行者123 更新时间:2023-12-01 08:17:12 24 4
gpt4 key购买 nike

Clojure 代理是一个强大的工具。由于使用函数“send”和“send-off”异步发送到代理的 Action ,理论上不会发生像死锁这样的事情。

是否可以使用我们有一些并发问题的代理编写一些 Clojure 代码(例如从某个 Action 调用另一个 Action 到另一个代理) - 它可能是死锁、竞争条件或其他任何事情。

最佳答案

sendsend-off将函数添加到代理队列并立即返回。因此,由于它们的异步特性,它们不可能发生死锁。

但是,send 使用的工作线程池用于计算工作,因此是一个固定的池大小(2 + # 核)。如果您(错误地)调用 send对于可以阻塞 I/O 或其他东西的任务,该任务将阻塞池中固定数量的 cpu 线程之一。如果您同时使用(2 + # 个内核)任务执行此操作,则可以有效地阻塞 cpu 线程池。解决办法当然是使用正确的send-off反而。 send-off 使用的工作线程池是无界的。

在操作中发送时,agents页面指​​出:

If during the function execution any other dispatches are made (directly or indirectly), they will be held until after the state of the Agent has been changed.



当调度发生在代理结束时,发送将项目放入发送队列并立即返回。由于代理从不阻塞等待资源,因此无法创建死锁循环。

也没有可能数据竞争 - 代理的状态应该是不可变的 Clojure 数据。代理在发送中应用更改功能并原子地替换代理的状态。读者(通过 dereference@ )在代理生命周期的某个时刻看到一个稳定的值。如果你需要读者和作者的协调,你必须使用 refs .

有可能是 竞争条件 : 两次调用 send来自不同线程的可以“竞争”被放入代理的队列中,并且并发读者可能会根据他们阅读代理时间线的时间感知不同(稳定)的值。然而,这是异步计算的本质。如果你想在读写多个资源时进行协调计算,你必须使用 refs .

关于concurrency - 在 Clojure 中是否有可能使用代理导致死锁(或其他坏情况)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8277576/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com