Resources
Shared resources with limited capacity are often needed in simulations.
- One approach to model them, is to use Julia
Channel
s with their API. This is thread-safe and thus should be preferred for multithreading applications. - Using
Resource
is a second possibility to model shared resources. Its interface gives more flexibility and is faster in single threaded applications, but in multithreading the user must avoid race conditions by explicitly wrapping access withlock -… access …- unlock
– if the resources are shared by multiple tasks.
DiscreteEvents.Resource
— TypeResource{T}(capacity)
A Resource implements a Deque
with a limited capacity. If used in multithreading applications, the user must avoid race conditions by explicitly wrapping modifying calls with lock-unlock
.
Fields
items::Deque{T}
: resource buffercapacity::Number=Inf
: the capacity is limited to the given integer,lock::ReentrantLock
: a lock for coordinating resource access by tasks.
Example
julia>
In order to use the full interface to Resource
you have to load DataStructures
.
DataStructures.capacity
— Functioncapacity(r::Resource)
Get the capacity of a resource
capacity(ch::Channel)
Get the capacity of a channel.
DataStructures.isfull
— Functionisfull(r::Resource)
Test whether the resource is full
isfull(ch::Channel)
Test whether a channel is full.
Base.isready
— Functionisready(r::Resource)
Test whether an item is available.
Base.isempty
— Functionisempty(r::Resource)
Test whether the resource is empty.
Base.empty!
— Functionempty!(r::Resource)
Reset the resource buffer (deque).
empty!(ch::Channel)
Reset a channel, throw away the elements stored to it.
Base.length
— Functionlength(r::Resource)
Get the number of elements available.
length(ch::Channel)
Get the number of items in a channel.
Base.push!
— Functionpush!(r::Resource, x)
Add an element to the back of a resource deque.
Base.pop!
— Functionpop!(r::Resource)
Remove an element from the back of a resource deque.
Base.pushfirst!
— Functionpushfirst!(r::Resource, x)
Add an element to the front of a resource deque.
Base.popfirst!
— Functionpopfirst!(r::Resource)
Remove an element from the front of a resource deque.
Base.first
— Functionfirst(r::Resource)
Get the element at the front of a resource deque.
Base.last
— Functionlast(r::Resource)
Get the element at the back of a resource deque.
Resource
provides a lock-unlock
API for multithreading applications.
Base.lock
— Functionlock(r::Resource)
Acquire the resource lock when it becomes available. If the lock is already locked by a different task/thread, wait for it to become available.
Each lock must be matched by an unlock.
Base.unlock
— Functionunlock(r::Resource)
Releases ownership of the resource lock.
If this is a recursive lock which has been acquired before, decrement an internal counter and return immediately.
Base.islocked
— Functionislocked(r::Resource)
Check whether the lock is held by any task/thread. This should not be used for synchronization (see instead trylock).
Base.trylock
— Functiontrylock(r::Resource)
Acquire the resource lock if it is available, and return true if successful. If the lock is already locked by a different task/thread, return false.
Each successful trylock must be matched by an unlock.