标签:协程 default -- src 两种 sele ide opened 才有
1 struct{}类型的chan只能接受struct{}{},其余的都不行,
package main import ( "fmt" "time" ) func fun1(m chan int) { time.Sleep(5*time.Second) m <- 4 } func fun2(m chan struct{}) { m <- struct{}{} } func main() { type s struct { name string } c1 := make(chan int) c2 := make(chan struct{}) //k := s{name: "tom"} // 由于c2是struc{}类型的channel,好像只能写入struct{}{},其它类型无法写入 // https://www.jianshu.com/p/7f45d7989f3a //c2 <- struct{}{} go fun1(c1) go fun2(c2) select { case p := <- c1: fmt.Println("c1接受到了值", p, c1) case q := <- c2: fmt.Println("c2接收到了值", q, c2) } }
Done()的用法就是在context对象结束时返回一个channel,瞎写的,
package main import ( "context" "fmt" "time" ) func main() { // 创建一个子节点的context,3秒后自动超时 // WithTimeout()函数接受一个 Context 和超时时间作为参数,即context的过期时间, // 返回其子Context和取消函数cancel ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) go watch(ctx, "监控1") go watch(ctx, "监控2") fmt.Println("现在开始等待8秒,time=", time.Now().Unix()) time.Sleep(8 * time.Second) fmt.Println("等待8秒结束,准备调用cancel()函数,发现两个子协程已经结束了,time=", time.Now().Unix()) // 若不调用cancel函数,到了原先创建Contetx时的超时时间,它也会自动调用cancel()函数, // 即会往子Context的Done通道发送消息 cancel() } // 单独的监控协程 func watch(ctx context.Context, name string) { for { select { // Done()函数 当ctx返回一个channel,若该channel为空,则 case k := <-ctx.Done(): fmt.Println("-----", k) fmt.Println(name, "收到信号,监控退出,time=", time.Now().Unix()) return default: fmt.Println(name, "goroutine监控中,time=", time.Now().Unix()) time.Sleep(1 * time.Second) } } } // 特别注意Done()返回的类型是struct{}类型的chan,这种chan只能在接收struct{}{}或close(chan)的时候才能结束读取, // 也即只有这两种情况才有返回值, //func (c *cancelCtx) Done() <-chan struct{} { // c.mu.Lock() // if c.done == nil { // c.done = make(chan struct{}) // } // d := c.done // c.mu.Unlock() // return d //}
ttt
标签:协程 default -- src 两种 sele ide opened 才有
原文地址:https://www.cnblogs.com/xxswkl/p/14198554.html