# Call function every N seconds

**URL:** <https://discourse.julialang.org/t/call-function-every-n-seconds/24611>\
**Category:** General Usage\
**Created:** [May 25, 2019, 10:21pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611 "2019-05-25T22:21:02Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [May 25, 2019, 10:21pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/1 "2019-05-25T22:21:02Z")

</div>

In Julia 1.x, is there a way to call a function every N seconds? Some details:

- reasonable delays in function calls are ok
- no task cooperation can be assumed, caller is allowed to run entirely within a single task without ever `yield`-ing
- if it matters, the function wraps a subroutine in a C library

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [May 25, 2019, 10:27pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/2 "2019-05-25T22:27:42Z")

</div>

Just a probably very dumb question: why not a dead simple `while true` loop with a timer?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [May 25, 2019, 10:38pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/3 "2019-05-25T22:38:06Z")

</div>

Sorry, I wasn’t clear enough - this functions should not stop execution of the main program flow. I work on a library ([RDKafka.jl](https://github.com/dfdx/RDKafka.jl)) that let’s you produce messages to a broker, but currently requires regular calls to `kafka_poll()` function to receive message delivery reports. I want to automate polling in background without stopping the main program flow.

In C or Java I would simply create a thread sleeping 99% of time, but in Julia we only have _cooperative_ multitasking and `@threads for ...`.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [May 26, 2019, 12:33am UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/4 "2019-05-26T00:33:47Z")

</div>

I think you’re looking for `Timer`.

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [May 26, 2019, 8:06am UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/5 "2019-05-26T08:06:11Z")

</div>

I believe you are talking about something like this:

```julia
t = Timer((t) -> println("running"), 1; interval=1) # print every 1 second

```

When running from REPL it indeed works. But REPL let’s scheduler switch between tasks. If we start a long-running not `yield`-ing task after the timer is created, the scheduler will wait for this task to finish before launching the timer callback:

```julia
t = Timer((t) -> print("\nrunning\n"), 1; interval=1)
for i=1:1000
    rand(1000, 1000) * rand(1000, 1000)
    # print(*)
end

```

On my computer timer starts printing the message only after 35 seconds. Notably, if I uncomment `print(*)` in the loop, Julia let’s scheduler switch tasks and timer works as expected again.

---

<div class="post-metadata">

**Author:** ![jpsamaroo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpsamaroo/32/46804_2.png) [@jpsamaroo](https://discourse.julialang.org/u/jpsamaroo)\
**Post date:** [May 26, 2019, 11:40am UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/6 "2019-05-26T11:40:34Z")

</div>

You would definitely need multithreading for this to work, since there’s no other (safe) way to do what you want with the regular libuv cooperative scheduler. The new PARTR threading facilities are probably what you’ll want to use; I won’t have time to put together an MWE today, but do check out the merged PRs with the “multithreading” tag on the julia Github to see some examples of how to use it.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [May 26, 2019, 11:47am UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/7 "2019-05-26T11:47:58Z")

</div>

I was about to write the same message at Julian. There is no safe way to do this without real threads. So if you can live with master (ie, 1.3), that is best.

You could create a thread in C, and do the poll on that thread, but even then doing a callback into Julia with the result will need the main thread to yield.

Regards

Avik

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [May 26, 2019, 8:35pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/8 "2019-05-26T20:35:20Z")

</div>

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

```julia
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).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 26, 2019, 10:47pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/9 "2019-05-26T22:47:08Z")

</div>

If your main thread is not doing any I/O, it’s usually not too hard to call `yield()` every once in a while… it’s mainly problematic if you are spending large blocks of time in external libraries that you can’t modify.

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [May 26, 2019, 10:55pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/10 "2019-05-26T22:55:39Z")

</div>

Since it’s a library code, I have no control over user’s code is doing. Although I believe in practice it won’t be a problem in most cases.

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [May 26, 2019, 11:02pm UTC](https://discourse.julialang.org/t/call-function-every-n-seconds/24611/11 "2019-05-26T23:02:40Z")

</div>

Thanks everyone, I’m excited to see new threading functionality in Julia 1.3. However, to maximize adoption of the library I think I will stick to @tkoolen solution based on timers and add caution to the README. Later we will be able to use `VERSION` to dispatch between the current hack and appropriate thread-based implementation.
