# How to coordinate shutting down tasks?

**URL:** https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434
**Category:** New to Julia
**Tags:** question, task
**Created:** [December 8, 2025, 3:17pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434 "2025-12-08T15:17:08Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)
#### Post date: [December 8, 2025, 3:17pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/1 "2025-12-08T15:17:08Z")

</div>

I use tasks to decouple subscribing to data streams and publish downstream data streams. I also use Bool references to coordinate when all tasks should exit.

Schematically, it looks like this:

```julia-auto
# main thread
run_flag = Threads.Atomic{Bool}(true)

# task1, subscribe
try
    while run_flag[]
        for msg in producerthing
            push!(channel, msg)
        end
    end
catch # if error set flag to end all other tasks
    run_flag[] = false
end

# task2, worker
while run_flag[]
    msg = take!(channel)
    # do stuff
end

```

This kind of works.

However, it has at least one failure mode: If task1 dies and calls `run_flag[] = false` and channel happens to be empty, then task2 will be waiting on the channel forever and never check that the `run_flag` has been set to false.

Are thread-safe boolean flags the correct way to coordinate this work? If yes, how would you implement this idea correctly? If not, how would you do it instead?

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [December 8, 2025, 3:29pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/2 "2025-12-08T15:29:43Z")

</div>

When I did something similar a few years ago, I put a termination message (or rather one message per task) on the channel. Since the normal messages contained a positive integer, I could conveniently encode the termination messages with a negative value.

---

<div class="post-metadata">

### Author: ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)
#### Post date: [December 8, 2025, 3:36pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/3 "2025-12-08T15:36:22Z")

</div>

Ok but in reality I have not just 2 tasks.

Imagine 5 tasks push!ing into the channel and one take!ing from it. If one of the pushing tasks crashes, how does it tell the other pushing tasks to exit? Or if I CTRL-C how do I coordinate that all tasks should exit? My design handles these cases (but has the same problematic edge case I described).

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [December 8, 2025, 3:45pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/5 "2025-12-08T15:45:23Z")

</div>

My case was certainly easier with a tree structure on the tasks and a dedicated channel for each group of workers.

What about both using an atomic Bool and sending a message to all downstream tasks when shutting down. It doesn’t even have to be a special message, just something to wake them up.

---

<div class="post-metadata">

### Author: ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)
#### Post date: [December 8, 2025, 3:45pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/6 "2025-12-08T15:45:54Z")

</div>

Yes, that’s what I do as you can see from my example. It has a problem which I describe and haven’t been able to solve yet. EDIT: I think the person I was responding to removed their message?

---

<div class="post-metadata">

### Author: ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)
#### Post date: [December 8, 2025, 3:46pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/7 "2025-12-08T15:46:45Z")

</div>

Ah, an atomic Bool from subscriber to subscriber, but a special message to downstream? I suppose could work. Not elegant though, right?

---

<div class="post-metadata">

### Author: ![freeman](https://avatars.discourse-cdn.com/v4/letter/f/ec9cab/32.png) [@freeman](https://discourse.julialang.org/u/freeman)
#### Post date: [December 8, 2025, 3:53pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/8 "2025-12-08T15:53:16Z")

</div>

I also have a non-elegant solution, which is to `close(channel)`. Then I need a try/except because take!ing from a closed channel triggered an InvalideStateException. It feels like a hack though.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [December 8, 2025, 4:15pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/9 "2025-12-08T16:15:42Z")

</div>

I’m just an amateur at multi-task programming, so all I can say is that my approach worked very nicely for my use case. But I never had to catch any exceptions and all shutdown was initiated due to the work being completed.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [December 8, 2025, 4:20pm UTC](https://discourse.julialang.org/t/how-to-coordinate-shutting-down-tasks/134434/10 "2025-12-08T16:20:34Z")

</div>

> [@freeman](#):
>
> I also have a non-elegant solution, which is to `close(channel)`. Then I need a try/except because take!ing from a closed channel triggered an InvalideStateException. It feels like a hack though.

I think this is likely the cleanest it can be with the current API. Unfortunately, `take!` doesn’t return a `Union{T, ChannelClosed}` or some other useful sum type that can communicate that the channel is closed intentionally.
