You are right, Brian.
The difference is not whether the channel is buffered or unbuffered - while
the receiver is present, none will encounter the deadlock.

package main

import (
    "fmt"
    "time"
    )

//var c = make(chan int)
var c = make(chan int, 2)

func report(){
    for{
        select{
        case n:= <- c:
            fmt.Println(n, time.Now().Format("2006-01-02 15:04:05"))
        default:
            time.Sleep(time.Second)
        }
    }
}

func main() {

    go report()

    for i:=1; i<=5; i++{
        c <- i
    }

}

But obviously, the buffered channel provides another layer of support in
case the receiver is temporarily absent:

package main

import (
    "fmt"
    "time"
    )

//var c = make(chan int)
var c = make(chan int, 5)

func report(){
    for{
        select{
        case n:= <- c:
            fmt.Println(n, time.Now().Format("2006-01-02 15:04:05"))
        default:
            time.Sleep(time.Second)
        }
    }
}

func main() {

    for i:=1; i<=5; i++{
        c <- i
    }

    report()

}


> I made up a work around that just dumps the new message if the buffer is
> full:
>
> You don't need to do that: use select { ... } to check if the channel is
> ready to receive or not.
> https://go.dev/play/p/Mb7VVCTvnfk
>
> But in practice, this is almost never needed, because one goroutine is
> doing the sending and a different goroutine is doing the receiving.  The
> sending goroutine blocks until the receiver is ready.
>
> On Wednesday, 13 April 2022 at 09:40:22 UTC+1 yan.z...@gmail.com wrote:
>
>> Since I found if inserting into a buffered channel could cause a crash if
>> it is full already
>> ( now I only use unbuffered channels in work)
>> https://groups.google.com/g/golang-nuts/c/U8lz6noKkuA
>>
>> package main
>>
>> var c = make(chan int, 1)
>>
>> func main() {
>>
>>     c <- 1
>>     c <- 2 //fatal error: all goroutines are asleep - deadlock!
>>     c <- 3
>>
>> }
>>
>> I made up a work around that just dumps the new message if the buffer is
>> full:
>>
>> package main
>>
>> import (
>>     "fmt"
>>     "sync"
>>     )
>>
>> type ChanInt struct{
>>     Ch chan int
>>     Mu *sync.Mutex
>> }
>>
>> var c = ChanInt{make(chan int, 1), new(sync.Mutex)}
>>
>> func (ch ChanInt) Fill(k int){
>>     ch.Mu.Lock()
>>     defer ch.Mu.Unlock()
>>
>>     if len(ch.Ch) < cap(ch.Ch){
>>         ch.Ch <- k
>>     }
>> }
>>
>> func main() {
>>
>>     fmt.Println("Channel Status: ",len(c.Ch), cap(c.Ch))
>>     c.Fill(5)
>>     fmt.Println("Channel Status: ", len(c.Ch), cap(c.Ch))
>>     fmt.Println("get one out of Channel:", <-c.Ch)
>>     fmt.Println("Channel Status: ", len(c.Ch), cap(c.Ch))
>>
>>     c.Fill(6)
>>     // c.Ch <- 7 //fatal error: all goroutines are asleep - deadlock!
>>     c.Fill(7)
>>     fmt.Println("Channel Status: ", len(c.Ch), cap(c.Ch))
>>     fmt.Println("get one out of Channel:", <-c.Ch)
>> }
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/6ExktXrF5Xc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7df07f32-d7aa-45db-91d6-de75e18ad8d8n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/7df07f32-d7aa-45db-91d6-de75e18ad8d8n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CADEX6_VU3CcG2jcaXiCdVPTja4TEzDiwHsNhx3g4aGE7ypBpog%40mail.gmail.com.

Reply via email to