# Multithreading mystery

**URL:** https://discourse.julialang.org/t/multithreading-mystery/36922
**Category:** General Usage
**Tags:** multithreading
**Created:** [April 2, 2020, 9:56pm UTC](https://discourse.julialang.org/t/multithreading-mystery/36922 "2020-04-02T21:56:07Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [April 2, 2020, 9:56pm UTC](https://discourse.julialang.org/t/multithreading-mystery/36922/1 "2020-04-02T21:56:07Z")

</div>

Is this a bug or am I misusing/misunderstanding `@sync`/`@spawn`?

```julia
julia> function f()
           x = 0
           @sync while x < 3
               @spawn println(x)
               x += 1
           end
       end
f (generic function with 1 method)

julia> f()
3
3
3

```

---

<div class="post-metadata">

### Author: ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)
#### Post date: [April 2, 2020, 10:07pm UTC](https://discourse.julialang.org/t/multithreading-mystery/36922/2 "2020-04-02T22:07:23Z")

</div>

In Julia 1.4 you can use `$` to copy the current value of `x` into the macro. I think you see this behavior because the outer while loop has already finish before the thread from `Threads.@spawn` starts. By than `x=3` and gets printed.

```julia
function f()
   x = 0
   @sync while x < 3
      Threads.@spawn println($x)
      x += 1
   end
end

```

---

<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: [April 2, 2020, 10:41pm UTC](https://discourse.julialang.org/t/multithreading-mystery/36922/3 "2020-04-02T22:41:50Z")

</div>

Note that at their core `@spawn code` and `@async code` are just syntax sugar of `schedule(Task(() -> code))`. So, normal caveats of closures apply. See:

```julia
julia> function f()
           x = 0
           funcs = []
           while x < 3
               push!(funcs, () -> println(x))
               x += 1
           end
           for g in funcs
               g()
           end
       end
f (generic function with 3 methods)

julia> f()
3
3
3

```

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [April 3, 2020, 7:12am UTC](https://discourse.julialang.org/t/multithreading-mystery/36922/4 "2020-04-03T07:12:22Z")

</div>

Thanks both. My takeaway is that `@macroexpand` is the key to understanding what’s going on and that much caution is required when using a variable inside `@spawn` that is defined outside `@sync`.
