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.
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
How to modify this code if I do not know the after what time exactly the jobs should close. You are using 2 seconds which is fine for this case. But what if process_node is a more complicated function.
One possible solution it is to use some special values/type to mark the end of valid values to be processed and close the channel, I will update my answer.