Reputation: 5020
I've got some threads returned by core.async/thread
involved in some process, which I'm about to shut down. I'm not shutting down my entire program, just these threads. How can I terminate the threads?
The .stop
method of the Java Thread
class is deprecated but I'd be happy to use it, except that core.async/thread
returns not a Thread
, but a ManyToManyChannel
:
user=> (clojure.core.async/thread)
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x780e97c0
"clojure.core.async.impl.channels.ManyToManyChannel@780e97c0"]
user=> (type *1)
clojure.core.async.impl.channels.ManyToManyChannel
I haven't found any documentation on ManyToManyChannel
. That sounds like a strange name for the type of a thread, so there might be something elementary here that I don't understand. But here's my current naïve, nonsensical-sounding question: How do you kill a ManyToManyChannel
?
clojure.repl/thread-stopper
seems to have no effect on ManyToManyChannel
s.
Upvotes: 4
Views: 1882
Reputation: 9266
You let the thread terminate naturally. If external termination is necessary, you have to implement it.
(defn terminatable [input-ch terminate-ch]
(thread
(loop []
(let [[v ch] (alts!! [input-ch terminate-ch])]
(if (identical? ch input-ch)
(if (some? v)
(do (process-input v) (recur))
;; else input-ch has closed -> don't call recur,
;; thread terminates
)
;; else we received sth. from terminate-ch,
;; or terminate-ch has closed -> don't call recur,
;; thread terminates
)))))
Then terminate externally via
(close! terminate-ch)
Finally you can determine when the thread is terminated by taking from the channel returned by thread
.
I. e.
(take! (terminatable (chan) (doto (chan) close!))
(fn [_] (println "Thread is terminated")))
Upvotes: 3