Call function every N seconds

Since I’ve been experimenting with related features, I’ll post something which works on yesterday’s nightly (with PARTR):

using Base.Threads
const ctr=Ref(0)
const amidone=Ref(false)
function upd(t)
  ctr[] += 1
end
t = Timer(upd, 1; interval=1)
function periodicjob()
    while isopen(t)
        wait(t)
        c = ctr[]
        println("running $c")
    end
end

function crunch()
    for i=1:1000
          rand(1000, 1000) * rand(1000, 1000)
    end
    println("loop done")
    amidone[] = true
end

if nthreads() == 1
    crunch()
else
    @threads for j=1:2
        id = threadid()
        if id == 1
            tHdl = @task periodicjob()
            schedule(tHdl)
        else
            cHdl = @task crunch()
            schedule(cHdl)
        end
    end
end

# N.B.: controller must stay alive
while !amidone[]
    sleep(0.1)
end
close(t)

IIUC, it is important that the thread 1 code yield (or be trivial). The periodicjob may need to run on thread 1 (or on the thread where its Timer lives?) for consistent timing.

Experiments with more substantial subsidiary tasks suggest that the overhead is modest, but I haven’t thought of a good way to verify that the primary (crunch) task is truly continuous (when BLAS is limited to one thread).

1 Like