Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Threads.@spawn and Threads.@threads?

I am a novice programmer interested in the Julia language. The documentation (https://docs.julialang.org/en/v1/base/multi-threading/) says Threads.@threads is for "for" loops and theads.@spawn places a given task on any available thread. My understand is that Threads.@threads is inherently synchronized while the threads.@spawn method is asynchronous and needs more planning to implement (namely using the fetch() method).

In code I find online using both, I seem to see the two used interchangeably (from my perspective). What is the conceptual difference between the two for a novice programmer and how/when should we implement each? Additionally, can they complement each other?

like image 202
noobquestionsonly Avatar asked May 20 '20 04:05

noobquestionsonly


People also ask

What is thread spawn?

Function std::thread::spawnSpawns a new thread, returning a JoinHandle for it. The join handle provides a join method that can be used to join the spawned thread. If the spawned thread panics, join will return an Err containing the argument given to panic! .

What is thread in Rust?

An executing Rust program consists of a collection of native OS threads, each with their own stack and local state. Threads can be named, and provide some built-in support for low-level synchronization.

What is a thread in a server?

A thread is a basic unit of CPU utilization, consisting of a program counter, a stack, and a set of registers, ( and a thread ID. ) Traditional ( heavyweight ) processes have a single thread of control - There is one program counter, and one sequence of instructions that can be carried out at any given time.

Are threads dependent on each other?

Threads are not independent of one another like processes are, and as a result threads share with other threads their code section, data section, and OS resources (like open files and signals). But, like process, a thread has its own program counter (PC), register set, and stack space.


1 Answers

Consider:

function withthreads()
    arr = zeros(Int, 10)
    Threads.@threads for i in 1:10
       sleep(3 * rand())
       arr[i] = i
    end
    println("with @threads: $arr")
end


function withspawn()
    arr = zeros(Int, 10)
    for i in 1:10
        Threads.@spawn begin
            sleep(3 * rand())
            arr[i] = i
        end
    end
    println("with @spawn: $arr")
end

function withsync()
    arr = zeros(Int, 10)
    @sync begin
        for i in 1:10
           Threads.@spawn begin
               sleep(3 * rand())
               arr[i] = i
           end
        end
    end
    println("with @sync: $arr")
end

withthreads()
withspawn()
withsync()

output:

with @threads: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
with @spawn: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
with @sync: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

So @threads manages the pool of threads allotted to julia, and spawns up to one thread for each iteration of the for loop (possibly using the same threads more than once for more than one iteration, sequentially as each thread finishes its allotted iteration, if there are more iterations than threads), and also synchonizes the threads, not exiting the for block until all threads have completed. @spawn spawns just one task thread and returns to the main task immediately, and so the block can be exited as soon as all tasks are spawned, even before they are done working (so the zeros remain 0 in array arr).

like image 160
Bill Avatar answered Oct 21 '22 18:10

Bill