Utilities for working with multithreaded workers for Julia services and applications
The package is registered in the General
registry and so can be installed at the REPL with ] add ConcurrentUtilities
.
ConcurrentUtilities.init(nworkers=Threads.nthreads() - 1)
Initialize background workers that will execute tasks spawned via
ConcurrentUtilities.@spawn
. If nworkers == 1
, a single worker
will be started on thread 1 where tasks will be executed in contention
with other thread 1 work. Background worker tasks can be inspected by
looking at ConcurrentUtilities.WORKER_TASKS
.
ConcurrentUtilities.@spawn expr
ConcurrentUtilities.@spawn passthroughstorage expr
Similar to Threads.@spawn
, schedule and execute a task (given by expr
)
that will be run on a "background worker" (see ConcurrentUtilities.init
).
In the 2-argument invocation, passthroughstorage
controls whether the task-local storage of the
current_task()
should be "passed through" to the spawned task.
Lockable(value, lock = ReentrantLock())
Creates a Lockable
object that wraps value
and
associates it with the provided lock
.
lock(f::Function, l::Lockable)
Acquire the lock associated with l
, execute f
with the lock held,
and release the lock when f
returns. f
will receive one positional
argument: the value wrapped by l
. If the lock is already locked by a
different task/thread, wait for it to become available.
When this function returns, the lock
has been released, so the caller should
not attempt to unlock
it.