jus*_*nhj 6 printf multithreading clojure slime
当我在emacs中从Swank repl运行Clojure代码时,主线程将使用printf将消息打印到repl.但是如果我运行代理或显式创建其他也打印的线程,有时输出不会显示,有时它会显示在我运行Swank的控制台窗口中.我很想知道为什么.
编辑:感谢丹尼尔的回答下面我现在知道了其他线程不必了绑定到REPL的输出.此代码有效,因为您从运行的位置传出.但是我的新问题是这个代码现在阻塞每个线程,所以不是并行运行,而是每次运行一个线程,所以我需要一个更多线程感知的输出方法.
(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)))))))
Run Code Online (Sandbox Code Playgroud)
原因是,在其他线程中*out*
没有绑定到 REPL 的流。尝试这样的事情:
(let [repl-out *out*]
(defn foo []
(binding [*out* repl-out]
...)))
Run Code Online (Sandbox Code Playgroud)
现在,当foo
从另一个线程运行时,*out*
将绑定到定义函数时的任何内容(即 SLIME REPL),因此打印将按预期工作。
或者,为了测试:
(defmacro future-output [& body]
`(let [out# *out*]
(future
(binding [*out* out#]
~@body))))
Run Code Online (Sandbox Code Playgroud)
注意:这是未经测试的,因为我这里没有可用的 Clojure/SLIME,但该代码在几个月前就可以工作。新版本的 Clojure (1.3 Alpha 2)可能存在差异:
- 对于常见情况,使用 vars 的代码路径现在要 快得多,并且您必须明确要求 :dynamic 可绑定性
归档时间: |
|
查看次数: |
556 次 |
最近记录: |