"Partially" synchronizing asynchronous tasks

The @sync / @async pair is very useful for waiting a series of asynchronous tasks to complete:

@sync for element in collection
   @async perform_task(element)
end

Is there a way to do something similar, but instead of waiting for all tasks to complete it is only necessary to wait for the completion of a certain number of tasks before continuing?

Reading the Tasks section of the documentation I found things like istaskdone, wait, notify and Condition but couldn’t figure out how they work and if they are implementable for this purpose.

What I can do for now is:

task = Array{Task}(undef, length(collection))

for (i, el) in enumerate(collection)
    task[i] = @async perform_task(el)
end

while sum(istaskdone.(task)) < n_tasks
    sleep(0.1)
end

Any recommendations on something better than sleep?

The “synchronize by communicating” approach would be for each task to send a signal across a shared channel when it’s done and have a single task reading those signals and doing something once a certain number of them have been received.

2 Likes