I've read this great article about core.async here:
http://www.core-async.info/reference/primitives
I'm struggling to understand the internal mechanic of put! and go. I understand that:
I don't understand:
Thanks a lot for shedding the lights on those mysteries.
If you want to understand how core.async channels work, there's no better source than Rich Hickey's EuroClojure 2014 presentation: Implementation details of core.async channels.
As for your specific questions:
If put!
is not accepted immediately, it places a pending put (the value to be put on the channel + the put!
callback) on a queue internal to the channel. Note that an exception will be thrown if there is no room in the queue (max capacity is currently fixed at 1024).
The callback will be called on a pooled thread if (1) the put is not immediately accepted or (2) an explicit false
is passed in as a final argument to the put!
call (this argument is called on-caller?
, see put!
's docstring for details).
"Parking", in the context of go
blocks, refers to suspending execution of a go
block's state machine by recording certain details of its current state and saving them inside a channel, or possibly several channels, so that it can be restarted later. (Note that this arrangement means that if all the channels holding references to a suspended go
block are GC'd, the go
block itself can also be GC'd.) In other contexts it similarly refers to putting a thread of control in a state of suspended animation. put!
is just a function (well, it's backed by a protocol method, but then that is just a protocol method), so the concept doesn't apply.
Yes. It basically steps through the code in the go
block, possibly suspending it when control reaches certain "custom terminals" (<!
, >!
, alt!
).
Not necessarily, you should first consider the risk of overflowing the internal queue (see point 1 above).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With