Julia: understanding when task switching occurs

I could not find detailed documentation about the @async macro. From the parallelism docs, I understand that only one system thread is used inside the Julia process, and the yieldto function explicitly switches tasks - correct me if I am wrong about this.

It’s hard for me to understand exactly when these task switches happen just by looking at the code, and knowing when this happens is crucial.

As I understand it, yieldto somewhere in the code (or in some function called by the code) should be there to ensure that the system is not stuck with just one task.

For example, when there is a read operation, there is probably a wait call inside the read, and there is probably a yieldto call in the wait implementation. I thought that without calling yieldto code would be stuck in one task; however, the execution of the example below seems to incorrectly confirm this hypothesis.

 @async begin # Task A while true println("A") end end while true # Task B println("B") end 

This code produces the following output

 BA BA BA ... 

It is very unclear to me where the task is switched inside the task created by the @async macro in the above code.

How can I talk about how to look at some code for the points at which the task is switched?

+6
source share
1 answer

The task switcher happens inside a call to println("A") , which at some point calls write(STDOUT, "A".data) . Since isa(STDOUT, Base.AsyncStream) and there is no more specialized method, this allows:

 write{T}(s::AsyncStream,a::Array{T}) at stream.jl:782 

If you look at this method, you will notice that it calls stream_wait(ct) for the current ct task, which in turn calls wait() .

(Also note that println not atomic, as there is a wait potential between writing arguments and a new line.)

Of course, you can determine when this happens if you look at all the code used. But I don’t understand why you need to know this for sure, because when working with parallelism you should not depend on processes that do not change the context. If you are dependent on a specific execution order, synchronize explicitly.

(You already noticed this in your question somehow, but let me repeat it here: as a rule, when using green threads, you can expect potential context switches when doing I / O, since locking for I / O is an example of a tutorial why green threads useful first.)

+4
source

Source: https://habr.com/ru/post/972903/


All Articles