Channels and Conditions: How to do notify channel is ready

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

Please post code as text instead of a screenshot. Also, please post enough code so that people here can run it. PSA: make it easier to help you

2 Likes