Multithreading 如何在Clojure中使用轻量级线程?
我试着用Clojure重写这个锈迹代码:Multithreading 如何在Clojure中使用轻量级线程?,multithreading,clojure,Multithreading,Clojure,我试着用Clojure重写这个锈迹代码: fn main() { let nums = [1, 2]; let noms = ["Tim", "Eston", "Aaron", "Ben"]; let mut odds = nums.iter().map(|&x| x * 2 - 1); for num in odds { spawn(proc() { println!("{:s} says hello from
fn main() {
let nums = [1, 2];
let noms = ["Tim", "Eston", "Aaron", "Ben"];
let mut odds = nums.iter().map(|&x| x * 2 - 1);
for num in odds {
spawn(proc() {
println!("{:s} says hello from a lightweight thread!", noms[num]);
});
}
}
下面是Clojure代码,它与上面提到的Rust代码几乎相同
(def noms ["Tim", "Eston", "Aaron", "Ben"])
(doseq [i (take-nth 2 (rest noms))]
(println i "says hello from a lightweight thread!"))
除非它不使用线程
您可以使用
future
生成线程。在这种情况下,您可以执行以下操作:
(doseq [i (take-nth 2 (rest noms))]
(future (print (str i " says hello from a lightweight thread!\n"))))
注意术语:使用futures的clojure示例并没有创建一个轻量级线程,而是一个本机OS线程。Rust在默认情况下也会这样做,但它有一个提供轻量级语义的绿色线程运行时。参考: Clojure默认不支持轻量级线程,但您可以通过库创建它们。所以代码看起来像这样:
(require '[clojure.core.async :as async :refer :all])
(doseq [i (take-nth 2 (rest noms))]
(go (print (str i " says hello from a lightweight thread!\n"))))
上面的go
宏将创建一个适当的轻量级线程*
*正如评论中指出的那样,该语句并不清楚,因此我将尝试澄清:core.async由Java线程池支持,但是go
宏将代码转换为使用“驻车”而不是“阻塞”的状态机。这只意味着您可以使用有限数量的实际线程来支持数以万计的go块
然而,当使用阻塞IO时,这一好处受到阻碍,正如下面提到的@hsestupin所解释的
要了解core.async如何在JVM上拥有轻量级线程,我建议从这里开始:-这是一个深入了解go
宏内部的精彩视频
宏本身是实现的请注意此处使用的
str
,否则数字和消息的其余部分可能会在线程之间混淆。使用go宏的代码无法正常工作。它有时打印1行,有时打印3行。怎么了<代码>用户=>(doseq[i(取第n个2(rest noms))]#=>(go(print(str i“从轻量级线程打招呼!\n”))Ben从轻量级线程打招呼!nil user=>(doseq[i(取第n个2(rest noms))]#=>(go(print(str i“从轻量级线程打招呼!\n”))Eston从轻量级线程打招呼!本从一个轻量级线程打招呼!Eston从一个轻量级线程向您问好!nil user=>上面的go宏将创建一个合适的轻量级线程,你是认真的吗?你能解释一下怎么做吗?或者请提供一个到官方文档/源dode的链接。我建议您阅读这篇文章,这篇文章有很好的解释,但要非常清楚,JVM上的core.async是由Java线程池支持的。当core.async用于clojurescript(在浏览器中)时,它默认为JS运行时事件循环,如本精彩视频中所述:文章链接已断开。使用。