[英]Future vs Thread: Which is better for working with channels in core.async?
When working with channels, is future
recommended or is thread
?使用渠道时,是future
推荐还是thread
? Are there times when future
makes more sense?是否有future
更有意义的时候?
Rich Hickey's blog post on core.async recommends using thread
rather than future
: Rich Hickey 关于 core.async 的博客文章建议使用thread
而不是future
:
While you can use these operations on threads created with eg future, there is also a macro, thread , analogous to go, that will launch a first-class thread and similarly return a channel, and should be preferred over future for channel work.虽然您可以在使用例如 future 创建的线程上使用这些操作,但还有一个宏 thread ,类似于 go,它将启动一个一流的线程并类似地返回一个通道,并且应该优先于 future 进行通道工作。
~ http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html ~ http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html
However, a core.async example makes extensive use of future
when working with channels:但是,core.async 示例在使用通道时广泛使用了future
:
(defn fake-search [kind]
(fn [c query]
(future
(<!! (timeout (rand-int 100)))
(>!! c [kind query]))))
~ https://github.com/clojure/core.async/blob/master/examples/ex-async.clj ~ https://github.com/clojure/core.async/blob/master/examples/ex-async.clj
In general, thread
with its channel return will likely be more convenient for the parts of your application where channels are prominent. 通常,具有通道返回的thread
对于通道突出的应用程序部分可能更方便。 On the other hand, any subsystems in your application that interface with some channels at their boundaries but don't use core.async internally should feel free to launch threads in whichever way makes the most sense for them. 另一方面,应用程序中与其边界处的某些通道接口但未在内部使用core.async的任何子系统都可以随意以最适合它们的方式启动线程。
thread
and future
thread
与future
之间的差异 As pointed out in the fragment of the core.async blog post you quote, thread
returns a channel, just like go
: 正如您引用的core.async博客文章的片段中所指出的, thread
返回一个频道,就像go
:
(let [c (thread :foo)]
(<!! c))
;= :foo
The channel is backed by a buffer of size 1 and will be closed after the value returned by the body of the thread
form is put on it. 该通道由大小为1的缓冲区支持,并且在将thread
表的主体返回的值放在其上之后将关闭。 (Except if the returned value happens to be nil
, in which case the channel will be closed without anything being put on it -- core.async channels do not accept nil
.) (除非返回的值恰好是nil
,在这种情况下,通道将关闭而不会放置任何内容 - core.async通道不接受nil
。)
This makes thread
fit in nicely with the rest of core.async. 这使得thread
非常适合core.async的其余部分。 In particular, it means that go
+ the single-bang ops and thread
+ the double-bang ops really are used in the same way in terms of code structure, you can use the returned channel in alt!
特别是,它意味着go
+单声道操作和thread
+双重操作在代码结构方面确实以相同的方式使用,你可以在alt!
使用返回的通道alt!
/ alts!
/等alts!
(and the double-bang equivalents) and so forth. (和双重等价物)等等。
In contrast, the return of future
can be deref
'd ( @
) to obtain the value returned by the future
form's body (possibly nil
). 相比之下, future
的回报可以是deref
( @
)来获得future
形式的主体返回的值(可能是nil
)。 This makes future
fit in very well with regular Clojure code not using channels. 这使得future
非常适合使用不使用通道的常规Clojure代码。
There's another difference in the thread pool being used -- thread
uses a core.async-specific thread pool, while future
uses one of the Agent-backing pools. 正在使用的线程池还有另一个不同之处 - thread
使用特定于core.async的线程池,而future
使用其中一个代理支持池。
Of course all the double-bang ops, as well as put!
当然所有的双重操作,以及put!
and take!
并take!
, work just fine regardless of the way in which the thread they are called from was started. ,无论从哪个线程调用它们的方式开始,都可以正常工作。
it sounds like he is recommending using core. 听起来他建议使用核心。 async's built in thread macro rather than java's Thread class. async的内置线程宏而不是java的Thread类。
http://clojure.github.io/core.async/#clojure.core.async/thread http://clojure.github.io/core.async/#clojure.core.async/thread
Aside from which threadpool things are run in (as pointed out in another answer), the main difference between async/thread
and future
is this:除了在哪个线程池中运行(如另一个答案中所指出的)之外, async/thread
和future
之间的主要区别在于:
thread
will return a channel which only lets you take!
thread
将返回一个只让你take!
的频道take!
from the channel once before you just get nil, so good if you need channel semantics, but not ideal if you want to use that result over and over在你得到 nil 之前从通道一次,如果你需要通道语义,那么好,但如果你想一遍又一遍地使用该结果,那就不理想了future
returns a dereffable object, which once the thread is complete will return the answer every time you deref
, making it convenient when you want to get this result more than once, but this comes at the cost of channel semantics相比之下, future
返回一个 derefable 对象,一旦线程完成,每次deref
都会返回答案,这在您想要多次获得此结果时很方便,但这是以通道语义为代价的If you want to preserve channel semantics, you can use async/thread
and place the result on (and return a) async/promise-chan
, which, once there's a value, will always return that value on later take!
如果您想保留通道语义,您可以使用async/thread
并将结果放在(并返回) async/promise-chan
上,一旦有值,它将始终在以后返回该值take!
s. s。 It's slightly more work than just calling future
, since you have to explicitly place the result on the promise-chan
and return it instead of the thread
channel, but buys you interoperability with the rest of the core.async
infrastructure.它比只调用future
稍微多一些工作,因为您必须明确地将结果放在promise-chan
并返回它而不是thread
通道,但是为您购买了与core.async
基础结构其余部分的互操作性。
It almost makes one wonder if there shouldn't be a core.async/thread-promise
and core.async/go-promise
to make this more convenient...这几乎让人怀疑是否不应该有一个core.async/thread-promise
和core.async/go-promise
来使这更方便......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.