使用swank / slime了解Clojure中的输出

时间:2010-12-26 05:21:35

标签: multithreading clojure printf slime

当我在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)))))))

2 个答案:

答案 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所在的位置)。