来自 http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ :
To get a bit more concrete let's see what happens when we try to issue some HTTP GET request using core.async. Let's start with the naive solution, using blocking IO via clj-http.
(defn blocking-get [url] (clj-http.client/get url)) (time (def data (let [c (chan) res (atom [])] ;; fetch em all (doseq [i (range 10 100)] (go (>! c (blocking-get (format "http://fssnip.net/%d" i))))) ;; gather results (doseq [_ (range 10 100)] (swap! res conj (<!! c))) @res )))
Here we're trying to fetch 90 code snippets (in parallel) using go blocks (and blocking IO). This took a long time, and that's because the go block threads are "hogged" by the long running IO operations. The situation can be improved by switching the go blocks to normal threads.
(time (def data-thread (let [c (chan) res (atom [])] ;; fetch em all (doseq [i (range 10 100)] (thread (>!! c (blocking-get (format "http://fssnip.net/%d" i))))) ;; gather results (doseq [_ (range 10 100)] (swap! res conj (<!! c))) @res )))
“go 块线程被长时间运行的 IO 操作占用”是什么意思?
最佳答案
Go 块旨在成为一种轻量级的协作线程;它们通过在池中使用几个线程并在停放时切换 go 块,以比完整 JVM 线程更少的开销提供类似线程的行为 - 例如,当使用 <!
在 channel 上等待时.当您调用阻塞JVM线程的块中的方法时,线程切换无法工作,因此您很快就会耗尽JVM线程。大多数标准 Java(和 Clojure)IO 操作在等待时都会阻塞当前线程。
关于multithreading - 在 core.async 中阻塞与线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30356521/