Warm tip: This article is reproduced from serverfault.com, please click

Julia: @sync not passing control to the rest of the Julia function

发布于 2020-12-07 15:15:48

I am trying to understand the usage of @sync and @async macros in Julia. I am trying to get this MWE to work and the program does not terminate. Any help is appreciated.

function process_node(nodes, id)
    @show id
    sleep(1.0)
    nodes[id] = true 
    return
end 

function main() 
    nodes = Dict( i => false for i in 1:10 )
    jobs = Channel{Int}(15)
    for i in 1:10 
        put!(jobs, i)
    end 
    @sync for id in jobs
        @async process_node(nodes, id)
    end 
    println("done")
end 


main()

The program never gets to the line println("done"). I do not know why.

Thanks in advance.

Questioner
user62089
Viewed
2
attdona 2020-12-08 01:57:58

There is nothing wrong about the use of @sync and @async in this example.

the loop for id in jobs never return because it blocks forever waiting endlessy for values no more inserted into the Channel.

Directly from the docs:

The returned Channel can be used as an iterable object in a for loop, in which case the loop variable takes on all the produced > values. The loop is terminated when the channel is closed.

One solution is to signal the end of the streams of values with a special Int value, for example -1 or if this is not possible with a nothing value, declaring jobs as Channel{Union{Int, Nothing}}.

function main() 
    nodes = Dict( i => false for i in 1:10 )
    jobs = Channel{Int}(15)
    for i in 1:10 
        put!(jobs, i)
    end 
    put!(jobs, -1)

    @sync for id in jobs
        if id == -1
            close(jobs)
        else
            @async process_node(nodes, id)
        end
        
    end
    
    println("done")
end