# Appending arrays in @threads

**URL:** <https://discourse.julialang.org/t/appending-arrays-in-threads/40496>\
**Category:** New to Julia\
**Tags:** parallel\
**Created:** [May 31, 2020, 2:12am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496 "2020-05-31T02:12:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![drhandwerk](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@drhandwerk](https://discourse.julialang.org/u/drhandwerk)\
**Post date:** [May 31, 2020, 2:12am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/1 "2020-05-31T02:12:40Z")

</div>

What’s the correct way to achieve three arrays of size 10 related to the following?

```
A = []; B = []; C = [];

Threads.@threads for i = 1:10
   append!(A,i)
   append!(B,i)
   append!(C,i)
end

```

The above either works, doesn’t append all 10 values to all three arrays, or appends #undef to a location. The order they are appended doesn’t matter.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [May 31, 2020, 2:22am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/2 "2020-05-31T02:22:03Z")

</div>

`append!` isn’t thread safe, so the result is really undefined. I believe this will work, you will use 3 threads to populate A, B, and C at the same time.

```julia
Threads.@threads for a in [A, B, C]
    for i in 1:10
       append!(a,i)
    end
end

```

---

<div class="post-metadata">

**Author:** ![drhandwerk](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@drhandwerk](https://discourse.julialang.org/u/drhandwerk)\
**Post date:** [May 31, 2020, 3:19am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/3 "2020-05-31T03:19:24Z")

</div>

Thanks for the response. My actual code isn’t as simple as appending the same number to 3 different arrays.

```
function buildAdjacency!(g::Graph)
n = length(g.nodes)
Is = []
Js = []
Vs = []
Threads.@threads for e in g.edges 
	# add edge to A
	append!(Is,findfirst(isequal(e.first), g.nodes))
	append!(Js,findfirst(isequal(e.second), g.nodes))
	append!(Vs,e.weight)
end
g.A = sparse(Is,Js,Vs,n,n)
end

```

Is there a thread-safe way to parallelize the loop over the edges?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 31, 2020, 6:01am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/4 "2020-05-31T06:01:09Z")

</div>

if you only have 3 accumulators (I J V), then the 3 threads approach still works

---

<div class="post-metadata">

**Author:** ![ppalmes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ppalmes/32/6838_2.png) [@ppalmes](https://discourse.julialang.org/u/ppalmes)\
**Post date:** [May 31, 2020, 7:59am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/5 "2020-05-31T07:59:52Z")

</div>

use ReentrantLock: [Multi-Threading · The Julia Language](https://docs.julialang.org/en/v1/base/multi-threading/)

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [May 31, 2020, 11:21am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/6 "2020-05-31T11:21:36Z")

</div>

For this, what might be easiest is:

```julia
function buildAdjacency!(g::Graph)
    n = length(g.nodes)
    Is = []
    Js = []
    Vs = []
    @sync
        Threads.@spawn for e in g.edges 
            append!(Is,findfirst(isequal(e.first), g.nodes))
        end
        Threads.@spawn for e in g.edges 
            append!(Js,findfirst(isequal(e.second), g.nodes))
        end
        Threads.@spawn for e in g.edges 
        	append!(Vs,e.weight)
        end
    end
    g.A = sparse(Is,Js,Vs,n,n)
end

```

That way each thread is adding to a different array. This works best if the calculations each thread has to do are different (you can’t really reuse any intermediate calculations between the threads).

The `ReentrantLock` @ppalmes suggested would also work. It does impose some overhead so it’s effectiveness will be based on how long `findfirst` takes to execute (in this example)…if it’s short then there could be lots of blocking, if it’s long things will run fine.

Edit: I **think** the `@sync` will work here, but I’m not 100%. You might need to save the the t1, t2, t3 tasks then do a wait on them just before the `sparse` function. like:

```julia
t1 = Threads.@spawn for end
t2 = Threads.@spawn for end
t3 = Threads.@spawn for end
wait(t1); wait(t2); wait(t3)

```

---

<div class="post-metadata">

**Author:** ![ppalmes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ppalmes/32/6838_2.png) [@ppalmes](https://discourse.julialang.org/u/ppalmes)\
**Post date:** [May 31, 2020, 11:27am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/7 "2020-05-31T11:27:45Z")

</div>

it is always a trade-off so better you benchmark it to see which ones are faster depending on data size and how often different threads access the same memory. @distributed can be faster so you may also compare @threads with it.

---

<div class="post-metadata">

**Author:** ![ppalmes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ppalmes/32/6838_2.png) [@ppalmes](https://discourse.julialang.org/u/ppalmes)\
**Post date:** [May 31, 2020, 11:31am UTC](https://discourse.julialang.org/t/appending-arrays-in-threads/40496/8 "2020-05-31T11:31:24Z")

</div>

don’t use the lock during find, only during append so that the lock can be released immediately.
