# Thread lock with async channel?

**URL:** <https://discourse.julialang.org/t/thread-lock-with-async-channel/8674>\
**Category:** Julia at Scale\
**Tags:** question\
**Created:** [January 29, 2018, 5:10pm UTC](https://discourse.julialang.org/t/thread-lock-with-async-channel/8674 "2018-01-29T17:10:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jwu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jwu/32/3775_2.png) [@jwu](https://discourse.julialang.org/u/jwu)\
**Post date:** [January 29, 2018, 5:10pm UTC](https://discourse.julialang.org/t/thread-lock-with-async-channel/8674/1 "2018-01-29T17:10:56Z")

</div>

The @threads seems not working well with async channel. the following code blocks forever, is there something wrong?

```julia
using Base.Threads

c = Channel{Int}(1)

mutex = SpinLock()

@sync begin 
    @async begin 
# for i in 1:10
        @threads for i in 1:10
            lock(mutex)
            push!(c, i)
            unlock(mutex)
        end 
    end
    
    @async begin 
        while true
            lock(mutex)
            i = take!(c)
            unlock(mutex)
            println(i)
        end
    end
end
close(c)

```

---

<div class="post-metadata">

**Author:** ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)\
**Post date:** [January 29, 2018, 11:30pm UTC](https://discourse.julialang.org/t/thread-lock-with-async-channel/8674/2 "2018-01-29T23:30:19Z")

</div>

Not answering your question, but I am curious if `lock` / `unlock` pattern is common, would a `@locked` macro like this be useful?

```julia
julia> using Base.Threads: lock, unlock

julia> macro locked(mutex, block)
           quote
               lock($mutex)
               value = $block
               unlock($mutex)
               value
           end |> esc
       end
@locked (macro with 1 method)

julia> using Base.Threads: SpinLock, @threads

julia> c = Channel{Int}(1)
Channel{Int64}(sz_max:1,sz_curr:0)

julia> m = SpinLock()
Base.Threads.TatasLock(Base.Threads.Atomic{Int64}(0))

julia> @threads for i in 1:10
           @locked m begin
               push!(c, i)
               take!(c) |> println
           end
       end
1
2
3
4
5
6
7
8
9
10

julia> close(c)

```

I think this is deadlocking, is there a way to check if a mutex is locked?

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [January 31, 2018, 3:37am UTC](https://discourse.julialang.org/t/thread-lock-with-async-channel/8674/3 "2018-01-31T03:37:25Z")

</div>

`@async` blocks are managed with `Tasks`. So are `Channels`. `Tasks` are currently implemented through the event-loop infrastructure of `libuv`, which is not thread-safe. Perhaps one of the developers can explain this strange design decision.

Even without threads, I think you need more logic, probably with an explicit `yield`, to avoid deadlock.
