# How to kill thread?

**URL:** <https://discourse.julialang.org/t/how-to-kill-thread/34236>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [February 6, 2020, 5:25am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236 "2020-02-06T05:25:10Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [February 6, 2020, 5:25am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/1 "2020-02-06T05:25:10Z")

</div>

Is there a way to kill a thread spawned by Threads.@spawn macro?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 6, 2020, 5:39am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/2 "2020-02-06T05:39:08Z")

</div>

Can you perhaps use `Base.throwto` to throw an exception to the task?

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [February 6, 2020, 5:50am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/3 "2020-02-06T05:50:54Z")

</div>

Thank you for your reply. I will give it a go as you suggest.

Actually I needed to be more specific. I am trying to do the following:

`Threads.@spawn run(pipeline(`adb shell "logcat -v time | grep onScanResult"`, io))`

Initially I discovered that `run()` was a blocking call and I could’t do anything after that. So I let a separate thread call `run()`.

I am naively expecting that if I could somehow kill the thread, then the process launched by that thread may also be killed…but this is a wrong understanding?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [February 6, 2020, 5:55am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/4 "2020-02-06T05:55:44Z")

</div>

> [@Sijun](#):
>
> but this is a wrong understanding?

I’m not sure about that, but I know that `Base.throwto` works well when throwing an exception to a task started with `@async`. Tasks on other threads might behave differently.

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [February 6, 2020, 6:22am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/5 "2020-02-06T06:22:58Z")

</div>

You need to get the task handle to kill it, like that:

```julia
using .Threads

function hanging()
    println("I'm hanging on thread:", threadid())
    while true
        sleep(1)
    end
end

julia> hang = Threads.@spawn hanging();

julia> I'm hanging on thread:2

julia> hang
Task (runnable) @0x000000010f5698d0

julia> schedule(hang, ErrorException("stop"), error=true)
Task (failed) @0x000000010f5698d0
stop
try_yieldto(::typeof(Base.ensure_rescheduled), ::Base.RefValue{Task}) at ./task.jl:611
....

```

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [February 6, 2020, 6:30am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/6 "2020-02-06T06:30:18Z")

</div>

Thank you for the detailed information! I think now I can leverage your code to put extra code to kill a process inside the thread before it’s death.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 6, 2020, 6:59am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/7 "2020-02-06T06:59:54Z")

</div>

According to @jameson, `schedule(..., error=true) ` is not the correct way to terminate the task already started and there is no way to safely interrupt a task. [Stop/terminate a (sub)task started with @async - #8 by jameson](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/8)

> [@Sijun](#):
>
> I am trying to do the following:
> 
> `Threads.@spawn run(pipeline(`adb shell “logcat -v time | grep onScanResult”`, io))`

First of all, you don’t need to use thread to run I/O concurrently. `@async` is enough. Also, for running external processes concurrently, you don’t even need to use `@async`:

```julia
julia> proc = run(`sleep 60`; wait = false)
Process(`sleep 60`, ProcessRunning)

julia> kill(proc)

julia> proc
Process(`sleep 60`, ProcessSignaled(15))

```

---

<div class="post-metadata">

**Author:** ![pbayer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pbayer/32/11675_2.png) [@pbayer](https://discourse.julialang.org/u/pbayer)\
**Post date:** [February 6, 2020, 8:08am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/8 "2020-02-06T08:08:44Z")

</div>

killing is never safe, I didn’t suggest otherwise. A safe way would be a task handling its own channel, like the following:

```julia
struct Stop end
struct Continue end

function safe_hanging(ch::Channel)
    println("I'm hanging on thread ", threadid())
    signal = Continue()
    while true
        isready(ch) && (signal = take!(ch))
        signal == Stop() && break
        sleep(1)
    end
    println("stopped!")
end

julia> mytask = Ref{Task}();

julia> ch = Channel(safe_hanging, taskref=mytask, spawn=true)
I'm hanging on thread 2
Channel{Any}(sz_max:0,sz_curr:0)

julia> mytask[]
Task (runnable) @0x000000011001f850

julia> put!(ch, Stop());
stopped!

julia> mytask[]
Task (done) @0x000000011001f850

```

Also a task with its own `try catch` error handling could be a safe way.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 6, 2020, 8:39am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/9 "2020-02-06T08:39:15Z")

</div>

Yes, you need so-called “cancellation token” for safe task cancellation. It would be nice to have a uniform API to do this in Julia. For more discussion see:

[https://github.com/JuliaLang/julia/issues/33248](https://github.com/JuliaLang/julia/issues/33248)

I also created a proof-of-concept that has an API `cancel!(::TaskContext)`: [GitHub - tkf/Awaits.jl: [WIP] Structured concurrency for parallel computing](https://github.com/tkf/Awaits.jl)

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [February 9, 2020, 1:43am UTC](https://discourse.julialang.org/t/how-to-kill-thread/34236/10 "2020-02-09T01:43:16Z")

</div>

@pbayer, @tkf, @baggepinnen, thank you all for your valuable instructions and concrete code examples!

It took me quite a while until I completely familiarized myself with every details in your answers.

@tkf, It took me days to catch the presence of `wait=false` in `run() call`. How silly of me!
