# Threads.@threads to return results

**URL:** <https://discourse.julialang.org/t/threads-threads-to-return-results/47382>\
**Category:** Internals & Design\
**Tags:** threads\
**Created:** [September 27, 2020, 11:46pm UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382 "2020-09-27T23:46:31Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![arabidopsis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arabidopsis/32/26457_2.png) [@arabidopsis](https://discourse.julialang.org/u/arabidopsis)\
**Post date:** [September 27, 2020, 11:46pm UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/1 "2020-09-27T23:46:32Z")

</div>

This is a request for “enhancement” I guess. It would be nice if  
`Threads.@threads returned the results. Something like:

```julia
v1, v2, v3 = Threads.@threads for w in [f1, f2, f3]
  w()
end

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [September 28, 2020, 12:27am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/2 "2020-09-28T00:27:40Z")

</div>

For loops don’t return a value…

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 28, 2020, 12:28am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/3 "2020-09-28T00:28:12Z")

</div>

if you are asking if that’s possible, it’s not.

It think something like this would work.

```julia
v = Vector{SomeType}(undef, 3)
fs = [f1, f2, f3]
Threads.@threads for i in 1:length(fs)
  v[i] = w(fs[i])
end

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 28, 2020, 4:07am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/4 "2020-09-28T04:07:03Z")

</div>

This should not be added to `Threads.@threads` since the macro has no way of knowing if there’s a return value. It’s obviously also inconsistent with normal for loop.

What you are looking for is a multithreaded map. I don’t think Base/Stdlib has it yet (though I didn’t check lately) but I’m pretty sure there are many packages that provide a similar API.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [September 28, 2020, 6:51am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/5 "2020-09-28T06:51:28Z")

</div>

I think this should do what you want:

```julia
v1, v2, v3 = fetch.(Threads.@spawn w() for w in [f1, f2, f3]) 

```

In many use cases, the spawn syntax is superior to `@threads` because it uses dynamic scheduling, e.g. is efficient also when the function run times are vastly different.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [September 28, 2020, 7:17am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/6 "2020-09-28T07:17:39Z")

</div>

> [@lungben](#):
>
> ```julia
> v1, v2, v3 = fetch.(Threads.@spawn w() for w in [f1, f2, f3]) 
> 
> ```

You’d need the parentheses around `Threads.@spawn w()` as in `((Threads.@spawn w()) for w in [f1, f2, f3])`.

> [@lungben](#):
>
> the spawn syntax is superior to `@threads` because it uses dynamic scheduling

FYI, `@threads` uses the mechanism same as `@spawn` since Julia 1.5. Though of course it’s true that `@spawn` is more flexible and `@threads` is not as dynamic as it could be.

* * *

For a more flexible `@threads`-like `for` loop syntax, see [GitHub - JuliaFolds/FLoops.jl: Fast sequential, threaded, and distributed for-loops for Julia—fold for humans™](https://github.com/JuliaFolds/FLoops.jl)

For parallel `map` and other `Base` functions, see [GitHub - tkf/ThreadsX.jl: Parallelized Base functions](https://github.com/tkf/ThreadsX.jl)

For other threaded map implementations, see:

- [GitHub - tro3/ThreadPools.jl: Improved thread management for background and nonuniform tasks in Julia. Docs at https://tro3.github.io/ThreadPools.jl](https://github.com/tro3/ThreadPools.jl)
- [GitHub - mohamed82008/KissThreading.jl: Simple patterns supporting working with threads in Julia](https://github.com/mohamed82008/KissThreading.jl)
- [GitHub - baggepinnen/ThreadTools.jl: Some tools for working with threads in Julia](https://github.com/baggepinnen/ThreadTools.jl)
- [GitHub - Jutho/Strided.jl: A Julia package for strided array views and efficient manipulations thereof](https://github.com/Jutho/Strided.jl)
- [GitHub - mcabbott/Tullio.jl: ⅀](https://github.com/mcabbott/Tullio.jl)
- [GitHub - invenia/Parallelism.jl: A library for threaded and distributed parallelism.](https://github.com/invenia/Parallelism.jl)

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [September 28, 2020, 7:26am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/7 "2020-09-28T07:26:50Z")

</div>

> [@tkf](#):
>
> You’d need the parentheses around `Threads.@spawn w()` as in `((Threads.@spawn w()) for w in [f1, f2, f3])` .

For me, the code works also without the parenthesis (tested in Pluto with Julia 1.5.1 before).

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 28, 2020, 7:32am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/8 "2020-09-28T07:32:40Z")

</div>

~~Yes, it works, but it will only spawn one task, not three, because without the parentheses it’s equivalent to `fetch.(Threads.@spawn(w() for w in [f1, f2, f3]))`.~~

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [September 28, 2020, 7:40am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/9 "2020-09-28T07:40:30Z")

</div>

I put `sleep(2)` in all 3 functions, and the total runtime of the command without the inner parenthesis was only about 2s, the same as if I would add the parenthesis as suggested by @tkf.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 28, 2020, 7:53am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/10 "2020-09-28T07:53:43Z")

</div>

That’s because the result is lazy, so the functions will only run once you actually access the items in the generator. I am wondering why it still takes 2s for you to run this, perhaps it’s just compilation time, or you are actually accessing the first element for some reason.

---

<div class="post-metadata">

**Author:** ![arabidopsis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arabidopsis/32/26457_2.png) [@arabidopsis](https://discourse.julialang.org/u/arabidopsis)\
**Post date:** [September 28, 2020, 7:57am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/11 "2020-09-28T07:57:23Z")

</div>

OK cool! Just the thing.

---

<div class="post-metadata">

**Author:** ![arabidopsis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arabidopsis/32/26457_2.png) [@arabidopsis](https://discourse.julialang.org/u/arabidopsis)\
**Post date:** [September 28, 2020, 8:02am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/12 "2020-09-28T08:02:43Z")

</div>

Thanks for references!

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [September 28, 2020, 8:36am UTC](https://discourse.julialang.org/t/threads-threads-to-return-results/47382/13 "2020-09-28T08:36:08Z")

</div>

Ah, sorry, I only checked

```julia
julia> (Threads.@spawn identity(w) for w in [1, 2, 3])
ERROR: syntax: unexpected ")"
Stacktrace:
 [1] top-level scope
   @ none:1

```

and

```julia
julia> ((Threads.@spawn identity(w)) for w in [1, 2, 3])
Base.Generator{Vector{Int64}, var"#41#43"}(var"#41#43"(), [1, 2, 3])

```

But you are right that

```julia
julia> identity.(Threads.@spawn identity(w) for w in [1, 2, 3])
3-element Vector{Task}:
 Task (done) @0x00007efe17835b60
 Task (done) @0x00007efe17835cd0
 Task (done) @0x00007efe17835e40

```

is equivalent to `identity.((Threads.@spawn identity(w)) for w in [1, 2, 3])`.
