Hi all,
I am doing an exercise with Julia and the Task related primitives.
It is a function that adds an array of integers from the left. There is also one symmetrical adding from the right.
In the main function i schedule both left and right, which should switch whenever the sum from one side exceeds the other, or the two meet before the sums become equal.
I use notify
and wait on a condition to restart each task, basically doing
- if left is smaller, sum left, put, notify and wait, take and repeat
- if right etc.
The issue is that put!
and notify
seem to be executing independently of each other in sumleft.
The print statement between them gives enough time for put!
to finish, but without it whole program blocks. How does notify
work? The main method also waits for the put!
operation to finish and then resumes the loop (either left or right depending on which is larger) by taking from a channel.
channel1 = Channel{Tuple{Int,Int}}(3)
channel2 = Channel{Tuple{Int,Int}}(3)
array = [1,2,3,4,1,1,9]
cond1 = Condition()
cond2 = Condition()
cond3 = Condition()
cond4 = Condition()
function sumleft()
accleft = 0
for (i, elem) in enumerate(array)
accleft += elem
put!(channel1, (accleft, i))
println("notifying left")
notify(cond3)
println("waiting for left...")
wait(cond1)
end
accleft
end
function sumright()
accright = 0
for (j, elem) in enumerate(reverse(array))
accright += elem
put!(channel2, (accright, j))
println("notifying right")
notify(cond4)
println("waiting for right...")
wait(cond2)
end
accright
end
function main()
a = Task(sumleft)
b = Task(sumright)
schedule(a)
println("scheduled a")
println("a status: ", istaskstarted(a))
schedule(b)
println("scheduled b")
println("b status: ", istaskstarted(b))
(accleft, accright) = 0, -1
(i ,j) = 0, 0
while accleft != accright && i < length(array) - j
println("notifying a and b")
if accleft > accright
println("take from channel right")
notify(cond2)
wait(cond4)
(accright, j) = take!(channel2)
elseif accright > accleft
println("take from channel left")
notify(cond1)
wait(cond3)
(accleft, i) = take!(channel1)
end
println("left channel: ", accleft, ' ', i)
println("right channel: ", accright, ' ', j)
end
[(accleft, i),(accright,j)]
end