CurrentModule = DiscreteEvents
Clocks schedule and execute actions, computations that happen as events at specified times (or under specified conditions).
A Clock
is not bound to physical time and executes an event sequence as fast as possible.
Clock
Clock(::T) where T<:Number
You can create clocks easily:
using DiscreteEvents, Unitful, .Threads
import Unitful: s, minute, hr
c = Clock() # create a unitless clock (standard)
c1 = Clock(1s, unit=minute) # create a clock with unit [minute]
c2 = Clock(1s) # create a clock with implicit unit [s]
c3 = Clock(t0=60s) # another clock with implicit unit [s]
c4 = Clock(1s, t0=1hr) # here Δt's unit [s] takes precedence
There is a default clock 𝐶
for experimental work:
𝐶
You can query the current clock time:
tau
Working with parallel clocks over multiple threads is a new feature in v0.3 and cannot yet considered to be stable. Please develop your applications first single-threaded before going parallel. Please report any failures.
Parallel clocks are virtual clocks with local clocks on parallel threads to support multi-threaded simulations.
A parallel clock structure consists of a master (global) clock on thread 1 and ActiveClock
s on all available threads > 1. An active clock is a task running a thread local clock. The thread local clock can schedule and execute events locally.
The master clock communicates with its parallel active clocks via message channels. It synchronizes time with the local clocks. Tasks (processes and actors) have access to their thread local clock from it and then work only with the local clock.
PClock
pclock
Parallel clocks can be identified by their thread number: the master clock works on thread 1, local clocks on parallel threads ≥ 2. They can be setup and accessed easily:
@show x=nthreads()-1;
clk = PClock() # now the clock has (+x) active parallel clocks
ac2 = pclock(clk, 2) # access the active clock on thread 2
ac2.clock # the thread local clock
ac2.clock.ac[] # local clocks can access their active clock
Tasks on parallel threads have access to the thread local clock by pclock(clk)
. Then they can schedule events, delay!
or wait!
on it as usual. The thread local clock is passed to a process!
automatically if you set it up on a parallel thread.
You can fork explicitly existing clocks to other threads or collapse them if no longer needed. You can get direct access to parallel active clocks and diagnose them.
fork!
collapse!
clk = Clock() # create a clock
fork!(clk) # fork it
clk # it now has parallel clocks
collapse!(clk) # collapse it
clk # it now has no parallel clocks
diagnose
Real time clocks are a new feature in v0.3 and thus cannot yet be considered as stable. Please try and report problems.
RTClock
s schedule and execute actions on a real (system) time line.
RTClock
createRTClock
stopRTClock
You can work with real time clocks easily:
rtc = createRTClock(0.01, 99) # create a real time clock
sleep(1)
tau(rtc) # query its time after a sleep
a = [1] # create a mutable variable
f(x) = x[1] += 1 # an incrementing function
event!(rtc, fun(f, a), every, 1) # increment now and then every second
sleep(3) # sleep 3 seconds
a[1] # query a
stopRTClock(rtc) # stop the clock
Virtual clocks can be run, stopped or stepped through and thereby used to simulate chains of events.
run!
@run!
incr!
resetClock!
stop!
resume!
sync!
You can set time units of a virtual clock:
setUnit!
!!! note
This is not yet implemented for parallel clocks!