# Threads.@threads and Threads.@spawn

**URL:** <https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502>\
**Category:** General Usage\
**Tags:** parallel, multithreading\
**Created:** [November 25, 2019, 4:18pm UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502 "2019-11-25T16:18:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dkiese](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@dkiese](https://discourse.julialang.org/u/dkiese)\
**Post date:** [November 25, 2019, 4:18pm UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502/1 "2019-11-25T16:18:15Z")

</div>

Hi everyone,

I have a short question regarding the usage of the `Threads.@spawn` macro in combination with `Threads.@threads`. Say I have code which looks like

```julia
some_task = Threads.@spawn begin 
        some_function_call_1()
        some_function_call_2() 
end 

for rep in reps

  #this is the main loop
  Threads.@threads for iter in iters
         do_main_work(iter)
  end

  wait(some_task)

  some_task = Threads.@spawn begin 
         some_function_call_1()
         some_function_call_2() 
  end 

end

```

I my naive understanding, the code does the following:

1.) Initializes `some_task` on one available thread  
2.) Enters the `reps` loop  
3.) Parallelize main work load (the inner loop) among available threads  
4.) Wait for ‘some\_task’ to finish  
5.) Run `some_task` on one available thread.  
6.) Continue with next iteration in `reps` loop with `some_task` still running

I have a few questions regarding this  
1.) Does this code actually do what I think it does?  
2.) If the respective thread is finished with `some_task` and the `iters` loop is still running, will the remaining workload be dynamically managed such that this thread does not become idle and can steal some work from the other threads?

I am using the current master branch for this.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [November 25, 2019, 5:08pm UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502/2 "2019-11-25T17:08:23Z")

</div>

This runs:

```julia
using Base.Threads

some_function_call_1() = begin
    println("some_function_call_1, ", Threads.threadid())
    sleep(rand())
end
some_function_call_2() = begin
    println("some_function_call_2, ", Threads.threadid())
    sleep(rand())
end
do_main_work(iter) = begin
    println("do_main_work, $(iter), ", Threads.threadid())
    sleep(rand())
end

some_task = Threads.@spawn begin 
    some_function_call_1()
    some_function_call_2() 
end 

for rep in 1:3
    Threads.@threads for iter in 1:4
        do_main_work(iter)
    end
    global some_task
    wait(some_task)
    some_task = Threads.@spawn begin 
        some_function_call_1()
        some_function_call_2() 
    end 
end

wait(some_task)

```

The output is

```julia
julia> include("c:/cygwin64/home/PK/thread_buffers.jl");
some_function_call_1, 2
do_main_work, 1, 1
do_main_work, 3, 2
do_main_work, 4, 2
some_function_call_2, 2
do_main_work, 2, 1
do_main_work, 1, 1
some_function_call_1, 2
do_main_work, 3, 2
do_main_work, 2, 1
some_function_call_2, 2
do_main_work, 4, 2
some_function_call_1, 2
do_main_work, 3, 2
do_main_work, 1, 1
do_main_work, 2, 1
some_function_call_2, 2
do_main_work, 4, 2
some_function_call_1, 2
some_function_call_2, 2

```

---

<div class="post-metadata">

**Author:** ![dkiese](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@dkiese](https://discourse.julialang.org/u/dkiese)\
**Post date:** [November 26, 2019, 8:40am UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502/3 "2019-11-26T08:40:47Z")

</div>

Many thanks for your answer. However, is there any reason why `some_task` is declared a global inside the `rep` loop (it has been initialized already in the outer scope)?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [November 26, 2019, 2:41pm UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502/4 "2019-11-26T14:41:58Z")

</div>

This has to do with the global scope in which the whole thing is written. Compare with

```julia

using Base.Threads

some_function_call_1() = begin
    println("some_function_call_1, ", Threads.threadid())
    sleep(rand())
end
some_function_call_2() = begin
    println("some_function_call_2, ", Threads.threadid())
    sleep(rand())
end
do_main_work(iter) = begin
    println("do_main_work, $(iter), ", Threads.threadid())
    sleep(rand())
end

function fun()
    some_task = Threads.@spawn begin 
        some_function_call_1()
        some_function_call_2() 
    end 

    for rep in 1:3
        Threads.@threads for iter in 1:4
            do_main_work(iter)
        end
        wait(some_task)
        some_task = Threads.@spawn begin 
            some_function_call_1()
            some_function_call_2() 
        end 
    end

    wait(some_task)

end

fun()

```

where the loops are inside function written for that purpose.

---

<div class="post-metadata">

**Author:** ![dkiese](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@dkiese](https://discourse.julialang.org/u/dkiese)\
**Post date:** [November 26, 2019, 3:25pm UTC](https://discourse.julialang.org/t/threads-threads-and-threads-spawn/31502/5 "2019-11-26T15:25:41Z")

</div>

Sure. Should have mentioned that the function is wrapped into a function in the actual code.
