I think something like this works fairly well. The other tasks will continue until the test in the while loop is encountered. But it’s possible to insert some done[] && return inside the loop as well.
function func_busy(i, done)
while !done[]
r = rand()
if r < 1e-10
done[] = true
@ccall printf("found one %.3le\n"::Cstring; r::Cdouble)::Cint
Libc.flush_cstdio()
return r
end
end
return nothing
end
function threaded_f(f)
c = Channel(1)
done = Threads.Atomic{Bool}(false)
tasks = [Threads.@spawn begin
local r = f(i, done)
isnothing(r) || put!(c, r)
end for i in 1:(Threads.nthreads()-1)]
println("taking")
res = take!(c)::Float64
println("result: ", res)
println("waiting for all tasks")
wait.(tasks)
close(c)
println("all done")
end
println(Threads.nthreads())
threaded_f(func_busy)
Note that it won’t work if nthreads() == 1.