Firstly, I am relatively new to julia, but have been enjoying it so far.
I am working on a parallel algorithm that requires multiple threads to read while one thread can update the vector, so my plan would be to use either a Ref or this atomic wrapper struct, but for some reason, both of these solutions end up blocking the main thread somehow which I’d think wouldn’t be possible from my MT experience in java.
In the below examples, it just simulates a bunch of reads and writes in parallel, but what is odd at least with testing here and in my actual case, when I use something like @btime or just run it multiple times with a large enough thread pool, it locks. What structures can I use to accomplish my goal while minimizing blocking?
- Edit: I should also note that I don’t care if it ends up in the correct ordering, as long as it updates often enough and doesn’t contain any invalid data. Sounds like immutable type stuff to me.
mutable struct AtomicWrapper{T}
@atomic x::T
end
read(avec::AtomicWrapper) = @atomic avec.x
write(avec::AtomicWrapper, val) = @atomic avec.x = val
function f2()
a = AtomicWrapper{Vector{Int}}(Int[])
val = [1, 2, 3]
write(a, val)
thread = @spawn begin
i = 0
while true
if i % 10 == 0
write(a, [])
else
write(a, [read(a)..., i])
end
i += 1
end
end
@threads for _ in 1:1000
println(read(a))
end
wait(thread)
end
function f()
a = Ref{Vector{Int}}(Int[])
val = [1, 2, 3]
a[] = val
worker = @spawn begin # Writes occurring while reads occurring
i = 0
# Since this is the only thread writing, no concurrent writes
while true
if i % 10 == 0
a[] = []
else
a[] = [a[]..., i]
end
i += 1
end
end
@threads for _ in 1:100
println(a[]) # Concurrent Reads
end
wait(worker)
end
for _ in 1:10
f()
end