A simple version of my question is “How can Task
s and Channel
s, which are coroutine-related, be used safely with threads?”
The “how” here is more in these sense of “how is it possible” than “how do I code it”, since there are already examples of that. Although it is also in the sense “how do I know which patterns are safe”?
The manual’s initial discussion of parallel computing describes the first approach as involving Task
s, coroutines, and Channel
s. The second approach uses threads. Even this initial discussion mentions threads being used to run Task
s.
Channel
s are presented as a way to safely communicate between coroutines. But this answer uses a Channel
to communicate between threads.
I would not assume that a mechanism that provided safe communication among coroutines would provide safe communication between OS threads, which have their own set of locking primitives. And I don’t see anything in the documentation of Channel
to suggest it is thread-safe.
But the manual clearly indicates that Task
s and coroutines are intended to go together, and a lot of responses in this forum by people clearly more familiar than I with parallelism in julia
do mix them. So what’s going on?
In particular, how do I know what forms of mixing are safe and what aren’t?
And how is it that they do mix? For example, architecturally is it that coroutines are used to manage the threads, so that they are really at 2 distinct layers?
My understanding is that coroutines, also known as green threads, are quite distinct from operating system threads. In some ways they are opposites. Green threads involve less overhead than OS threads and so solve the excessive resource demands of the latter. On the other hand, OS threads can preempt each other, while coroutines must explicitly yield control to allow others to run in a process referred to as cooperative multitasking. OS threads can use hardware resources for real parallel execution, while green threads are about letting each other work while they wait for input, i.e., the computer is only handling one at a time. Core.Task
is a coroutine according to the manual.