Last active
April 1, 2019 16:02
-
-
Save sunary/af22b392c949ae08112ac84b8b751192 to your computer and use it in GitHub Desktop.
Play with go channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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]) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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