实现两个goroutine通信,要求如下
- 实现pingpong效果
- 保证程序能任意时长执行,且收到ctrl+c信号之后,全身而退(即保证各个goroutine完整退出)
- 在第三个goroutine中,可随时查找前两个goroutine各自发送了多少个消息,并可设置各自pingpong的频率,如果同时有一万个goroutine过来查找呢
- 符合编码规范的前提下,代码质量控制在两位数
答案
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
var interval = 5 * time.Second
func main() {
ch1 := make(chan string, 0)
ch2 := make(chan string, 0)
sigs := make(chan os.Signal, 1)
count1Send := 0
count1Receive := 0
count2Send := 0
Count2Receive := 0
type check chan int
control := make(chan check, 10)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
for {
ch1 <- "ping"
count1Send++
time.Sleep(interval)
select {
case <-ch2:
count1Receive++
}
}
}()
go func() {
for {
select {
case <-ch1:
Count2Receive++
}
time.Sleep(interval)
ch2 <- "posng"
count2Send++
}
}()
go func() {
for {
c := <-control
<-c
fmt.Println("count1Send:", count1Send)
fmt.Println("count2Send:", count2Send)
fmt.Println("count1Receive:", count1Receive)
fmt.Println("count2Receive:", Count2Receive)
close(c)
}
}()
// check
go func() {
for {
time.Sleep(5 * time.Second)
c := make(check, 1)
c <- 1
control <- c
}
}()
select {
case <-sigs:
close(ch1)
close(ch2)
close(control)
fmt.Println("close program")
}
}
func setInterval(newInterval time.Duration) {
interval = newInterval
}