# How to avoid deadlocking on finite channel

**URL:** https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429
**Category:** General Usage
**Tags:** question
**Created:** [November 18, 2022, 8:20am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429 "2022-11-18T08:20:05Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![HANHAOHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hanhaohan/32/36366_2.png) [@HANHAOHAN](https://discourse.julialang.org/u/HANHAOHAN)
#### Post date: [November 18, 2022, 8:20am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/1 "2022-11-18T08:20:05Z")

</div>

code as following will deadlock.

```nohighlight
c = Channel(2)

t1 = Threads.@spawn begin
    while !trylock(c)
        yield()
        println("trylock for reading")
    end
    try
        put!(c, rand())
        put!(c, rand())
        put!(c, rand())
    catch e
        println(e)
    finally
        unlock(c)
    end
end

t2 = Threads.@spawn begin
    while !trylock(c)
        yield()
        println("trylock for reading")
    end
    try
        println("output:", take!(c))
    catch e
        println(e)
    finally
        unlock(c)
    end
end

```

how to solve it?  
The programe should be not deadlocking! Who know why?

---

<div class="post-metadata">

### Author: ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)
#### Post date: [November 18, 2022, 8:47am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/2 "2022-11-18T08:47:15Z")

</div>

I don’t think you need to manually lock anything, just use `put!` and `take!` normally will be enough. If a thread tries to take when there are no elements it will just wait. If you put when you at capacity, again, it will just wait. It’s probably simplest to take this approach.

```julia
c = Channel(2)

t1 = Threads.@spawn begin
    for i in 1:3
        put!(c, rand())
    end
end

t2 = Threads.@spawn begin
    v = take!(c)
    println("output: $v")
end

wait(t1)
wait(t2)

```

---

<div class="post-metadata">

### Author: ![HANHAOHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hanhaohan/32/36366_2.png) [@HANHAOHAN](https://discourse.julialang.org/u/HANHAOHAN)
#### Post date: [November 18, 2022, 9:01am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/3 "2022-11-18T09:01:05Z")

</div>

Thanks!  
But, why my code is not deadlocking, I locked it manually?

---

<div class="post-metadata">

### Author: ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)
#### Post date: [November 18, 2022, 9:05am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/4 "2022-11-18T09:05:48Z")

</div>

Because you lock the channel manually, and try to then `put!` elements inside? `put!` will internally lock the channel, you shouldn’t manually lock it, and it will wait to be able to lock.

Also, if your second thread manually locks `c` and then you try to `take!` and there are no elements it will hang forever as nothing can put anything into `c` as it is locked.

---

<div class="post-metadata">

### Author: ![HANHAOHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hanhaohan/32/36366_2.png) [@HANHAOHAN](https://discourse.julialang.org/u/HANHAOHAN)
#### Post date: [November 18, 2022, 9:12am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/5 "2022-11-18T09:12:43Z")

</div>

No, it is not that situation.

```julia
julia> c = Channel(2)
Channel{Any}(2) (empty)

julia> t1 = Threads.@spawn begin
           while !trylock(c)
               yield()
               println("trylock for reading")
           end
           try
               put!(c, rand())
               put!(c, rand())
               put!(c, rand())
           catch e
               println(e)
           finally
               unlock(c)
           end
       end
Task (runnable) @0x00007f18e088b990

julia> istaskdone(t1)
false

julia> Threads.@spawn begin
           @show trylock(c)
       end
Task (runnable) @0x00007f18e18cc8b0

julia> trylock(c) = true

```

---

<div class="post-metadata">

### Author: ![HANHAOHAN](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hanhaohan/32/36366_2.png) [@HANHAOHAN](https://discourse.julialang.org/u/HANHAOHAN)
#### Post date: [November 18, 2022, 9:20am UTC](https://discourse.julialang.org/t/how-to-avoid-deadlocking-on-finite-channel/90429/6 "2022-11-18T09:20:38Z")

</div>

> [@jmair](#):
>
> ou shouldn’t manually lock it, and it will wait to be able to lock.

Thanks again.  
I see now. You are right.  
I tried and find out that lock can be locked many times in one thread.  
`put!(c, "any")` check the condition itself, and the lock status be reset to the right one at the same.

So, Channel is thread safe.
