当我在emacs中从Swank repl运行Clojure代码时,主线程将使用printf将消息打印到repl。但是如果我运行代理或显式创建其他也打印的线程,有时输出不会显示,有时它会显示在我运行Swank的控制台窗口中。我很想明白为什么。
编辑:感谢Daniel的回答,我现在知道其他线程没有 out 绑定到REPL的输出。此代码有效,因为您从运行的位置传入 out 。但是我的新问题是这个代码现在阻塞每个线程,所以不是并行运行,而是每次运行一个线程,所以我需要一个更多线程感知的输出方法。
(defn sleeper-thread [out id t]
"Sleep for time T ms"
(binding [*out* out]
(printf "%d sleeping for time %d\n" id t)
(Thread/sleep t)
(printf "%d slept\n" id)))
(defn test-threads [n out]
(dotimes [x n]
(.start (Thread. (#(sleeper-thread %1 %2 %3) out x (+ 2000 (rand-int 5000)))))))
答案 0 :(得分:1)
原因是,在其他线程*out*
中没有绑定到REPL的流。尝试这样的事情:
(let [repl-out *out*]
(defn foo []
(binding [*out* repl-out]
...)))
现在,当从另一个线程运行foo
时,*out*
将绑定到您定义函数时的任何内容(即SLIME REPL),因此打印将按预期工作。
或者,测试:
(defmacro future-output [& body]
`(let [out# *out*]
(future
(binding [*out* out#]
~@body))))
注意:这是未经测试的,因为我在这里没有工作的Clojure / SLIME,但该代码几个月前就已经运行了。 newer Versions of Clojure(1.3 Alpha 2)可能存在差异:
- 现在使用vars的代码路径 对于常见情况,很多更快, 并且您必须明确要求:动态绑定
答案 1 :(得分:0)
如果您正在努力使用相同的蛋糕,那么项目根目录中的.cake / cake.log文件中应该有一个输出的日志文件(project.clj所在的位置)。