Skip to content

Run on any background thread #28

@SimonDanisch

Description

@SimonDanisch

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
end

Would this fit into ThreadPools?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions