-
Notifications
You must be signed in to change notification settings - Fork 8
Closed
Description
I created some code, to run work on any background thread:
const AVAILABLE_THREADS = Base.RefValue{Channel{Int}}()
function spawn_background(f)
# -1, because we don't spawn on foreground thread 1
nbackground = Threads.nthreads() - 1
if nbackground == 0
# we don't run in threaded mode, so we just run things async
log("Warning: no threads available, running in foreground thread")
return @async f()
end
# Initialize dynamically, could also do this in __init__ but it's nice to keep things in one place
if !isassigned(AVAILABLE_THREADS)
# Allocate a Channel with n background threads
c = Channel{Int}(nbackground)
AVAILABLE_THREADS[] = c
# fill queue with available threads
foreach(i -> put!(c, i + 1), 1:nbackground)
end
# take the next free thread... Will block/wait until a thread becomes free
thread_id = take!(AVAILABLE_THREADS[])
return ThreadPools.@tspawnat thread_id begin
try
return f()
catch e
# If we don't do this, we get pretty bad stack traces... not sure why!?
return CapturedException(e, Base.catch_backtrace())
finally
# Make thread available again after work is done!
put!(AVAILABLE_THREADS[], thread_id)
end
end
endWould this fit into ThreadPools?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels