# Why \`lock\` does NOT work for full channel?

**URL:** <https://discourse.julialang.org/t/why-lock-does-not-work-for-full-channel/65710>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 3, 2021, 1:55am UTC](https://discourse.julialang.org/t/why-lock-does-not-work-for-full-channel/65710 "2021-08-03T01:55:53Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![pyrex41](https://avatars.discourse-cdn.com/v4/letter/p/4bbf92/32.png) [@pyrex41](https://discourse.julialang.org/u/pyrex41)\
**Post date:** [August 3, 2021, 4:32am UTC](https://discourse.julialang.org/t/why-lock-does-not-work-for-full-channel/65710/5 "2021-08-03T04:32:20Z")

</div>

Actually, i think my answer was incorrect; some slight variations recover the same underlying problem, even with a separate lock:

```julia
function showme(n, m)
    c = Channel(m)
    l = ReentrantLock()
    t1 = @async begin
        for x in 1:n

            put!(c, 0)
            sleep(0.1)
        end
    end
    t2 = @async begin
        lock(l)
        for x in 1:n
            put!(c,1)
            sleep(0.001)
        end
        unlock(l)
    end

    d= []
    sleep(1)
    for _ in 1:2n
        push!(d, take!(c))
    end
    show(d)
end

```

```julia
julia> showme(5,5)
Any[0, 1, 1, 1, 1, 1, 0, 0, 0, 0]
julia> showme(5,4)
Any[0, 1, 1, 1, 1, 0, 1, 0, 0, 0]

```

After digging in, it appears that `lock(c::Channel)` calls `lock(c.cond_take.lock)`, the underlying `ReentrantLock` for the channel. And, your `put!` call ends up nesting `lock` calls (see [https://github.com/JuliaLang/julia/blob/master/base/channels.jl](https://github.com/JuliaLang/julia/blob/master/base/channels.jl), around line 313), and observe also:

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

julia> islocked(c.cond_put.lock)
false

julia> lock(c)

julia> lock(c)

julia> islocked(c.cond_put.lock)
true

julia> unlock(c)

julia> islocked(c.cond_put.lock)
true

julia> unlock(c)

julia> islocked(c.cond_put.lock)
false

```

My intuition is that these nested locks (which I don’t quite understand) are interacting with you asynchronous code in unanticipated ways. Perhaps your `lock` call in `t2` is nesting within a lock that is blocking triggered by a `put!` in `t1`?

It looks you can lock the calls within `t1` to get the behaviour you want:

```julia
function showme(n, m)
    c = Channel(m)
    t1 = @async begin
        for _ in 1:n
            lock(c)
            put!(c, 0)
            unlock(c)
            sleep(0.1)
        end
    end
    t2 = @async begin
        lock(c)
        for _ in 1:n
            put!(c,1)
            sleep(0.001)
        end
        unlock(c)
    end

    d= []
    sleep(1)
    for _ in 1:2n
        push!(d, take!(c))
    end
    show(d)
end

```

```julia
julia> showme(5,5)
Any[0, 1, 1, 1, 1, 1, 0, 0, 0, 0]
julia> showme(5,4)
Any[0, 1, 1, 1, 1, 1, 0, 0, 0, 0]

```

---

_[View the full topic](https://discourse.julialang.org/t/why-lock-does-not-work-for-full-channel/65710)._
