Fork me on GitHub
#core-async
<
2019-12-14
>
hindol05:12:01

Hi, is future a lightweight thread similar to go blocks?

hiredman06:12:59

"lightweight thread" is a kind of terrible term

hiredman06:12:42

I am not sure I would call go blocks lightweight threads either

hiredman06:12:27

When a go block is running it is a normal jvm (native) thread

hiredman06:12:30

But when "blocked" on a channel it yields the thread. But the amount of data the go block hangs on to can easily dwarf the amount of data needed for thread bookkeeping. So what even is lightweight?

hindol06:12:34

I kind of what you are trying to say.

hindol06:12:13

So, a go block is just description of work, and a thread might pick it up and do a bit of it till time slice runs out or it hits a blocking call. Is that correct?

hiredman06:12:52

There is no time slice for go blocks, they are effectively cooperatively scheduled

hiredman06:12:21

(the native thread it is running on of course can be preempted, but the go block has no idea of that happens and it doesn't cause it to yield the thread to other go blocks)

hindol06:12:30

So, when does the go block yield? Is it ONLY when it hits a parking call?

hiredman06:12:52

Yes, only on the special channel operations

hindol06:12:25

That clears it. So, go blocks in a way mandate the use of channels.

hiredman06:12:47

Blocking io, taking locks, burning cpu without doing channel ops will all blockup the thread pool where go blocks run

hindol06:12:32

I thought is was more general purpose. Thanks for the clarification.

hiredman06:12:31

The go macro is also a statically scoped transformation. So it only rewrites it's immediate body.

hindol06:12:54

You are referring to the concept where a go block stops at the function boundary? I read the official guide but did not understand it fully.

roklenarcic14:12:09

it will not work if you move <! into a function, it has to be in the go block

dharrigan14:12:19

I was a bit confused by that too. As a beginner, reading some of the documentation can be hard to unpick

dharrigan14:12:12

What does it mean that it stops at the function boundary?

Alex Miller (Clojure team)16:12:52

The parking functions only work in a go macro because the go macro rewrites the code around it. So once you call into a function the go macro can no longer “see” it to do any rewriting

dharrigan16:12:51

So, if I have something like this (go (if (pos? x) (anotherns/my-function x))), then what execution context will my-function have? In the sense of threads? On the same thread as the go-block, or elsewhere?

hiredman17:12:29

The same as the go block, and if my-function does any blocking operations it will clog up the threadpool

dharrigan17:12:33

understood about blocking, I'm trying to understand better, It's just that I'm trying to consoldate this "once you call into a function, the go macro...", with what happens when I call into a function, and how threads etc. are maintained/created

leonoel17:12:14

function boundary means if there's a fn form between go and a parking form, it's not considered to be part of it

leonoel17:12:20

so e.g in the following form (go (fn [] (<! c))) the <! will not be rewritten, and thus is illegal

dharrigan17:12:20

isn't <! async? why would it be parking?

leonoel17:12:02

parking operations are resolved at compile-time. if there's a function boundary between a parking operation and a go block, you can't know in advance the evaluation context, so the go macro just ignores it

dharrigan17:12:22

Looks like I'll have to do more reading into the subject. Thank you! 🙂