5 ms·
In core.async code inside (go) blocks are run via a fixed thread pool (a large one, but still fixed), when you use <! and >! the code after the put/take is turn
by _halgari 13y ago
In core.async code inside (go) blocks are run via a fixed thread pool (a large one, but still fixed), when you use <! and >! the code after the put/take is turned into a callback that is attached to the channel. The thread is then released back to the pool. This allows for extremely lightweight async code. In addition, goes can actually be GC'd when they deadlock and can never continue (all references to the channel a go is taking from are dropped).
Code inside (thread) blocks run on a dedicated thread. This allows for long running or IO bound processes to execute without clogging the main thread pool. Thread blocks do not rewrite their bodies into a state machine (unlike go blocks) and as such must use <!! and >!!. Since these threads are dedicated they do not return the thread to the thread pool when blocking. This allows for slightly better performance at the cost of an entire JVM thread for the life of the block.
TL;DR - Use <! and >! with go. Use <!! and >!! with thread. Mixing the two can have very unexpected results. In fact, using <! inside a thread block will result in a runtime exception.
- jbert 13y agoThanks. I misunderstood your (original, unedited) comment to refer to a golang goro (go func()), not clojure go macro. Yes - this seems to be a key difference of golang's approach. The runtime+scheduler conspire to make a blocking goro much cheaper than an OS thread.
- bkirkbri 13y agoI've enjoyed working with core.async once I understood these constraints. It would be nice for code to "know" whether it's within a go block or not. That would alleviate needing do-something! and do-something!! versions of some functions. By "know" I mean something like an in-go earmuff var. EDITED for clarification and formatting
- masklinn 13y ago> It would be nice for code to "know" whether it's within a go block or not. Part of it obviously does since `<!` can't be called outside of a go block. And cljs has somewhat less of an issue there as it does not have `<!!` (since without extension the language has very little allowances for blocking)