# Basic question about thread interaction

**URL:** https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532
**Category:** General Usage
**Tags:** multithreading, threads
**Created:** [February 8, 2026, 12:08am UTC](https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532 "2026-02-08T00:08:46Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![slwu89](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/slwu89/32/217323_2.png) [@slwu89](https://discourse.julialang.org/u/slwu89)
#### Post date: [February 8, 2026, 12:08am UTC](https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532/1 "2026-02-08T00:08:46Z")

</div>

Hi everyone. I’m trying to learn how to use threads in Julia by comparing them to the Python examples from Ramalho’s Fluent Python book [Fluent Python, 2nd Edition [Book]](https://www.oreilly.com/library/view/fluent-python-2nd/9781492056348/).

The basic Python example is:

```julia-auto
import itertools
import time
from threading import Thread, Event

def spin(msg: str, done: Event) -> None:
    for char in itertools.cycle(r'\|/-'):
        status = f'\r{char} {msg}'
        print(status, end='', flush=True)
        # returns False after s and keep looping
        # or if another treat calls Event.set(), return True and break loop
        if done.wait(.1):
            break
    blanks = ' ' * len(status)
    print(f'\r{blanks}\r', end='')

def slow() -> int:
    # blocks main thread, but releases GIL, so other threads can run
    time.sleep(3)
    # long function finishes
    return 42

def supervisor() -> int:
    done = Event() # starts as False
    spinner = Thread(target=spin, args=('thinking!', done))
    print(f'spinner object: {spinner}')
    spinner.start() # start spin thread
    result = slow() # blocks main thread
    done.set() # spin loop will end
    spinner.join() # wait for spin thread to end
    return result

supervisor()

```

I have a Julia implementation as (started Julia with 4 threads):

```julia-auto
using Base.Threads

function spin(msg::String, done::Threads.Atomic{Bool})
    for char in Iterators.cycle("\\|/-")
        status = "\r$(char) $(msg)"
        print(status)
        flush(stdout)
        sleep(0.1)
        if done[]
            break
        end
    end
    blanks = " " ^ (length(msg)+3)
    print("\r$(blanks)\r")
end

function slow()
    sleep(3)
    return 42
end

function supervisor()
    done = Threads.Atomic{Bool}(false);
    spinner = Threads.@spawn spin("thinking!", done)
    println("spinner object: $(spinner)")
    result = slow()
    done[] = true
    wait(spinner)
    return result
end

supervisor()

```

My question is twofold. First is this an idiomatic or Julian way to use `Threads.Atomic`? Secondly, could someone suggest how to accomplish this with `Event` or `Condition`? I found the documentation for those 2 types hard to follow. Thanks everyone.

---

<div class="post-metadata">

### Author: ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)
#### Post date: [February 10, 2026, 3:20am UTC](https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532/2 "2026-02-10T03:20:53Z")

</div>

May or may not be helpful: [GitHub - carstenbauer/LittleBookOfSemaphores.jl: Julia code snippets inspired by the Little Book Of Semaphores](https://github.com/carstenbauer/LittleBookOfSemaphores.jl)

---

<div class="post-metadata">

### Author: ![slwu89](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/slwu89/32/217323_2.png) [@slwu89](https://discourse.julialang.org/u/slwu89)
#### Post date: [February 10, 2026, 5:45am UTC](https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532/3 "2026-02-10T05:45:42Z")

</div>

Wow, had no idea someone (you) implemented this book in Julia! Not sure if immediately helpful yet, but certainly fascinating 🙂 Thank you for sharing.

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [February 10, 2026, 9:39am UTC](https://discourse.julialang.org/t/basic-question-about-thread-interaction/135532/4 "2026-02-10T09:39:23Z")

</div>

> [@slwu89](#):
>
> First is this an idiomatic or Julian way to use `Threads.Atomic`?

Yes, the `Atomic` use is idiomatic, but it’s wise to put thing inside a `try ... finally`:

```julia-auto
spinner = Threads.@spawn spin("thinking!", done)
result = try
    slow()
finally 
    done[] = true
    wait(spinner)
end

```

The reason is that if the `slow()` call throws, the spinner is anyway stopped.

> [@slwu89](#):
>
> could someone suggest how to accomplish this with `Event` or `Condition`?

An `Event` is used when you need to to wait until someone calls `notify`. E.g.

```julia-auto
e = Event()
t = @spawn (doit(); wait(e); something())
dostuff()
notify(e) # inform the spawned task that we have done stuff
wait(t) # wait for task to finish

```

A `Condition` is similar, but it does not remember that somebody has called `notify`. You have to be inside a `wait` when someone calls `notify` (edge-triggering). If you’re late to call `wait`, you’ll be waiting for the next `notify`. On the other hand, an `Event` will be “set” when someone calls `notify`, so subsequent `wait`ers will just continue.

`Event` and `Condition` are not very well suited for your regular checks in a loop. I don’t think there’s a public interface to check whether an `Event` has been set, it’s to be waited for, not checked. Though, an `Event` contains an atomic field `set`, so if you let your `done` be an `Event`, and check for `done.set`, it will work. But this is an undocumented implementation detail, and you’re better off by just using an `Atomic`.

There’s also a general `timedwait` function which can be used like the python `done.wait(.1)`, though it’s polling the supplied function, not waiting via the task scheduler:

```julia-auto
timedwait(() -> done, 0.1)

```
