Skip to content

Instantly share code, notes, and snippets.

@sunary
Last active April 1, 2019 16:02
Show Gist options
  • Save sunary/af22b392c949ae08112ac84b8b751192 to your computer and use it in GitHub Desktop.
Save sunary/af22b392c949ae08112ac84b8b751192 to your computer and use it in GitHub Desktop.
Play with go channel
# source https://play.golang.org/p/jwdtDXVHJk
package main
import (
"fmt"
"time"
)
func producer(iters int) <-chan int {
c := make(chan int)
go func() {
for i := 0; i < iters; i++ {
c <- i
time.Sleep(1 * time.Second)
}
close(c)
}()
return c
}
func consumer(cin <-chan int) {
for i := range cin {
fmt.Println(i)
}
}
func fanOut(ch <-chan int, size, lag int) []chan int {
cs := make([]chan int, size)
for i, _ := range cs {
// The size of the channels buffer controls how far behind the recievers
// of the fanOut channels can lag the other channels.
cs[i] = make(chan int, lag)
}
go func() {
for i := range ch {
for _, c := range cs {
c <- i
}
}
for _, c := range cs {
// close all our fanOut channels when the input channel is exhausted.
close(c)
}
}()
return cs
}
func fanOutUnbuffered(ch <-chan int, size int) []chan int {
cs := make([]chan int, size)
for i, _ := range cs {
// The size of the channels buffer controls how far behind the recievers
// of the fanOut channels can lag the other channels.
cs[i] = make(chan int)
}
go func() {
for i := range ch {
for _, c := range cs {
c <- i
}
}
for _, c := range cs {
// close all our fanOut channels when the input channel is exhausted.
close(c)
}
}()
return cs
}
func main() {
c := producer(10)
chans := fanOutUnbuffered(c, 3)
go consumer(chans[0])
go consumer(chans[1])
consumer(chans[2])
}
package main
import (
"context"
"fmt"
"math/rand"
"sync"
"time"
)
var lock sync.RWMutex
func sender(ctx context.Context, ch chan int) {
sendFail := 0
for {
mailToBeSent := rand.Int()
// no wait
select {
case <-ctx.Done():
fmt.Println("Total sent fail is:", sendFail, ". Now Bob quit!")
return
default:
lock.Lock()
select {
case oldmail := <-ch: // popout old mail
fmt.Println("Old mail", oldmail)
default:
}
ch <- mailToBeSent
lock.Unlock()
}
}
}
func receiver(ctx context.Context, ch chan int) {
for {
select {
case <-ctx.Done():
fmt.Println("Alice quit!")
return
default:
lock.RLock()
select {
case mail := <-ch:
fmt.Println("Alice received: ", mail)
time.Sleep(2000)
default:
}
lock.RUnlock()
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
ch := make(chan int, 1)
go sender(ctx, ch)
time.Sleep(2 * time.Millisecond)
go receiver(ctx, ch)
time.Sleep(10 * time.Millisecond)
cancel()
// wait for Alice and Bob to quit
time.Sleep(1 * time.Millisecond)
fmt.Println("Both Quit, now I quit!")
}
// https://play.golang.org/p/k9kcqA8K274
package main
import (
"fmt"
)
type DV interface {
Speak() string
}
type Cho struct {}
func (c *Cho) Speak() string {
return "xx"
}
type Meo struct {}
func (m *Meo) Speak() string {
return "yy"
}
func main() {
cho := Cho{}
fmt.Println(cho.Speak())
dv := []DV{
new(Cho),
new(Meo),
}
fmt.Println(dv[1].Speak())
}
package main
import (
"fmt"
"golang.org/x/tour/tree"
"sync"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t == nil {
return
}
defer wg.Done()
ch <- t.Value
go Walk(t.Left, ch)
go Walk(t.Right, ch)
}
var wg sync.WaitGroup
func main() {
wg.Add(10)
ch := make(chan int, 10)
go Walk(tree.New(1), ch)
go func(){
wg.Wait()
close(ch)
}()
for i := range ch {
fmt.Println(i)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment