t := map[string]int{ "a": 1 "b": 2}重排为t := make(map[string]int)t["a"]=1t["b"]=2
goroutine
语句
go f()
泄漏
阻塞不能自动结束 # 如操作channel时
main中最后调panic(), 从崩溃转储信息判断资源释放情况
死锁(deadlock) # 指没有可调度的goroutine
所有goroutine阻塞或没有goroutine
运行main的是主goroutine, main返回所有goroutine暴力终结
无id(标识)
不能中断
无返回值
runtime
context
time
并发模式 # 避免goroutine泄漏,保证通信顺序
done/quit
o-> done控制goroutine退出。 # 更快的响应要写更多的逻辑入侵,找到响应慢点写done逻辑func f(done <-chan struct{}) { select { case <-done: for range ch{ # 耗尽通道, 其它goroutine不会卡在ch<-上而退出 } return }}func cancelled()bool{ select { case <-done: return true default: return false }}func f2(){ # 轮循函数中入口检查, 避免创建新goroutine if cancelled() { return }}done := make(chan struct{})defer close(done)f(done)
channels of channels
o-> 循环处理请求func handle(reqs chan chan interface{}) { for req := range reqs { req <- 0 }}func server(req chan interface{}) { reqs := make(chan chan interface{}) defer close(reqs) go handle(reqs) reqs <- req}func client() interface{} { req := make(chan interface{}) defer close(req) go server(req) return <-req}fmt.Println(client())o-> 循环异常退出type S struct { closing chan chan error}func (s *S) close() error { errc := make(chan error) s.closing <- errc return <-errc}func (s *S) loop() { for { select { case errc := <-s.closing: errc <- nil return } }}
pipeline(fan-in, fan-out) # 传入传出channel来处理
o->func gen(done <-chan struct{}, nums ...int) <-chan int { out := make(chan int) go func() { defer close(out) for _, n := range nums { select { case out <- n: case <-done: return } } }() return out}func sq(done <-chan struct{}, in <-chan int) <-chan int { out := make(chan int) go func() { defer close(out) for n := range in { select { case out <- n * n: case <-done: return } } }() return out}func merge(done <-chan struct{}, cs ...<-chan int) <-chan int { # wg等cs数目个协程合并数据到out后,关闭out var wg sync.WaitGroup out := make(chan int) output := func(c <-chan int) { for n := range c { select { case out <- n: case <-done: } } wg.Done() } wg.Add(len(cs)) for _, c := range cs { go output(c) } go func() { wg.Wait() close(out) }() return out}func main() { done := make(chan struct{}) defer close(done) for n := range sq(done, sq(done, gen(done, 2, 3))) { # gen产生维护数字chan, sq产生维护平方chan。三个chan # 三个goroutine done()时return, chan return时close() fmt.Println(n) } // 扇出 in := gen(done, 2, 3) c1 := sq(done, in) c2 := sq(done, in) // 扇进 for n := range merge(done, c1, c2) { fmt.Println(n) }}