Quoting 伊藤和也 (2019-01-29 05:00:32)

>    I know the general meaning of a deadlock, but I don't know the meaning
>    of a deadlock in golang. For example, I send 4 values to a buffered
>    channel whose maxmum size is 3 and a deadlock occurs. I think this is
>    just "values are out of bounds" like array. What does a deaklock mean
>    in golang?

A deadlock means the same thing in Go as it does in general; there's no
language-specific concept here.

The error you're seeing isn't an "out of bounds" error, rather, on the
last send the channel is already full so the sending goroutine waits until
there is space to insert the new item. Since there is nothing that will
ever take stuff out of the channel, this is never going to happen --
therefore you have a deadlock.

If you modify the program so there is another goroutine which will
receive a value from the channel:

    package main

    import (
        "time"
    )

    func main() {
        ch1 := make(chan int, 3)
        go func() {
            time.Sleep(10 * time.Second)
            <-ch1
        }()
        ch1 <- 10
        ch1 <- 10
        ch1 <- 30
        ch1 <- 40
    }

then you won't get that error -- after the 10 second sleep, the spawned
goroutine will pull a value out of the channel, making space for one
more. At this point the send succeeds, the first goroutine is unblocked,
and the program finishes successfully.

Normally, the result of a deadlock is that things just hang, but because
channels are built-in to the language, and the compiler and runtime know
about them, it's possible for the runtime to spot certain patterns of
deadlocks. I mentioned this in another comment, but basically what's
happening is when the goroutine scheduler notices it doesn't have any
goroutines that are ready to run, it checks to see if any of them are
waiting on something that might unblock without the help of another
goroutine. If so, it waits until there's something to run. Otherwise it
reports an error, rather than just hanging.

In the first iteration of the program (in your original message), there
are no other goroutines at all, so when the scheduler sees that it's
only goroutine is waiting on a channel, it knows it will never finish
and bails.

In the modified version above, shortly after the program begins, the
original goroutine is again blocked on the channel send, but this time
there is another goroutine, which is blocked on a call to sleep. This
time, when the scheduler notices it has nothing to run, it also sees
that there is a goroutine waiting on sleep() -- which might finish
eventually, so it gives it some time, rather than aborting. When the
sleep completes, that goroutine can be scheduled and we're good.

It is of course possible to cause deadlocks that the runtime won't
catch; a variant of the above example that used os.Pipe() instead of
a channel would just hang, even though the same concurrency patterns
are at fault, because the goroutine scheduler doesn't know about pipes,
only channels.

-Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to