I was experimenting with multithreading to learn more about Julia’s multithreading capabilities. I tried to replicate the @spawn steps with ordinary Task creation:
function prime_check(n) for i = 2:n/2 if n%i == 0 return nothing end end return n end function primes_spawn!(A , value) cond = ReentrantLock() @sync for i = 2:value Threads.@spawn begin a = prime_check(i) if a != nothing lock(cond) push!(A, a) unlock(cond) end end end end function primes_task!(A, value::Int) cond = ReentrantLock() for i = 2:value let local task = Task(()->prime_check(i)) task.sticky = false schedule(task) if fetch(task) != nothing lock(cond) println(fetch(task), " running on thread ", threadid()) #push!(A, fetch(task)) unlock(cond) wait(task) end end end end
When I run it I get the following result:
A = Int64 primes_task!(A, 20)
2 running on thread 1 3 running on thread 1 5 running on thread 1 7 running on thread 1 11 running on thread 1 13 running on thread 1 17 running on thread 1 19 running on thread 1
Julia code warns the following:
#Note there are three reasons a Task might be put into a sticky queue
# even if t.sticky == false:
# 1. The Task’s stack is currently being used by the scheduler for a certain thread.
# 2. There is only 1 thread.
# 3. The multiq is full (can be fixed by making it growable).
But I don’t know where to fix it to make it work correctly.