This code really blows my mind, Brian! I didn't know select can be flexible 
as this:

package main

import (
    "fmt"
)

var Ch = make(chan int, 1)

func Fill(ch chan int, k int) {
    select {
    case ch <- k:
        // sent
    default:
        // discard
    }
}

func main() {

    fmt.Println("Channel Status: ", len(Ch), cap(Ch))
    Fill(Ch, 5)
    fmt.Println("Channel Status: ", len(Ch), cap(Ch))
    fmt.Println("get one out of Channel:", <-Ch)
    fmt.Println("Channel Status: ", len(Ch), cap(Ch))

    Fill(Ch, 6)
    // Ch <- 7 //fatal error: all goroutines are asleep - deadlock!
    Fill(Ch, 7)
    fmt.Println("Channel Status: ", len(Ch), cap(Ch))
    fmt.Println("get one out of Channel:", <-Ch)
}

在2022年4月13日星期三 UTC+8 17:49:58<Brian Candler> 写道:

> > 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 [email protected] 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 the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/223ebc9a-d7ac-4ef7-baea-f2dedbc7c787n%40googlegroups.com.

Reply via email to