Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia: understanding when task switching happens

I could not find detailed documentation about the @async macro. From the docs about parallelism I understand that there is only one system thread used inside a Julia process and there is explicit task switching going on by the help of the yieldto function - correct me if I am wrong about this.

For me it is difficult to understand when exactly these task switches happen just by looking at the code, and knowing when it happens seems crucial.

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

For example when there is a read operation, inside the read there probably is a wait call and in the implementation of wait there probably is a yieldto call. I thought that without the yieldto call the code would stuck in one task; however running the following example seems to prove this hypothesis wrong.

@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 switching happens inside the task created by the @async macro in the code above.

How can I tell about looking at some code the points where task switching happens?

like image 796
Kalevi Avatar asked Jul 27 '14 00:07

Kalevi


1 Answers

The task switch happens inside the call to println("A"), which at some point calls write(STDOUT, "A".data). Because isa(STDOUT, Base.AsyncStream) and there is no method that is more specialized, this resolves to:

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) on the current task ct, which in turn calls wait().

(Also note that println is not atomic, because there is a potential wait between writing the arguments and the newline.)

You could of course determine when stuff like that happens by looking at all the code involved. But I don't see why you would need to know this exactly, because, when working with parallelism, you should not depend on processes not switching context anyway. If you depend on a certain execution order, synchronize explicitly.

(You already kind of noted this in your question, but let me restate it here: As a rule of thumb, when using green threads, you can expect potential context switches when doing IO, because blocking for IO is a textbook example of why green threads are useful in the first place.)

like image 106
user4235730 Avatar answered Oct 20 '22 06:10

user4235730