Skip to content

Instantly share code, notes, and snippets.

@tailnode
Created January 1, 2018 03:22
Show Gist options
  • Save tailnode/3e784ba0f207d5831e69b2d3114c90b6 to your computer and use it in GitHub Desktop.
Save tailnode/3e784ba0f207d5831e69b2d3114c90b6 to your computer and use it in GitHub Desktop.
stop M sender N receiver using one channel
package main
import (
"fmt"
"math/rand"
"time"
)
const senderNum = 20
const receiverNum = 7
type t struct {
i int
senderNo int
}
var dataCh = make(chan t, 100)
var stopCh = make(chan struct{})
func main() {
startReceiver()
startSender()
// let sender and receiver run 3 second
stopSendDataAfterNSecond(3)
fmt.Println("stop transmit data")
// block to wait
time.Sleep(10 * time.Second)
}
func startSender() {
for i := 0; i < senderNum; i++ {
go func(i int) {
for {
if stopped() {
fmt.Printf("sender[%d] stop\n", i)
return
}
dataCh <- t{i: rand.Int(), senderNo: i}
sleepMs(1, 2)
}
}(i)
}
}
func startReceiver() {
for i := 0; i < receiverNum; i++ {
go func(i int) {
for {
if stopped() {
for {
select {
case result := <-dataCh:
fmt.Printf("sender stop but data channel still have data, reveiver[%d] get %d from sender[%d]\n", i, result.i, result.senderNo)
default:
fmt.Printf("receiver[%d] stop\n", i)
return
}
}
}
<-dataCh
//result := <-dataCh
//fmt.Printf("reveiver[%d] get %d from sender[%d]\n", i, result.i, result.senderNo)
sleepMs(0, 10)
}
}(i)
}
}
func stopSendDataAfterNSecond(t int) {
time.Sleep(time.Duration(t) * time.Second)
close(stopCh)
}
func stopped() bool {
select {
case <-stopCh:
return true
default:
return false
}
}
func sleepMs(min, max int) {
t := rand.Intn(max-min) + min
time.Sleep(time.Duration(t) * time.Millisecond)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment