go的goroutine 调用和channel的使用
开启goroutine :
var lwg sync.WaitGroup
func main() { go lian1() go lian2() go lian3() lwg.Add(3) fmt.Println("main") lwg.Wait() //等待其他协程结束 } func lian1() { fmt.Println("lian1") lwg.Done() } func lian2() { fmt.Println("lian2") lwg.Done() } func lian3() { fmt.Println("lian3") lwg.Done() }
无缓存的通道:
func main() { //无缓冲的通道,阻塞的通道 se := make(chan int) //有缓存的通道可以在本goroutines或者其他goroutines使用,但是没有缓存的通道只能和其他goroutines一起使用并造成串行 go lian4(se) //没有缓存的通道,只能先调用取值的goroutines,后面才能发送,如果先发送再取值会死锁 se <- 10 //发送 fmt.Println("发送成功") go lian5() go lian6() fmt.Println("main") time.Sleep(time.Millisecond * 5) } func lian4(se chan int) { fmt.Println("准备取值") res := <-se //没有缓存的通道,下一步一定是在这里取值之后才到其他地方,但是并不是一定要完整执行完当前方法才到其他地方,只是一定会到取值的位置而已 fmt.Println("接收成功", res) fmt.Println("lian4") } func lian5() { fmt.Println("lian5") } func lian6() { fmt.Println("lian6") }
有缓存的通道:
func main() { ch := make(chan int, 2) ch <- 1 ch <- 2 close(ch) //在接收方明确等待通道关闭的信号时才需要执行关闭操作,建议手动执行关闭操作,不然循环取值的时候会死锁;通道关闭了还是能取值,但是不能发送值 lian7(ch) } func lian7(ch chan int) { for v := range ch { //当通道被关闭后,会在通道内的所有值被接收完毕后会自动退出循环 fmt.Println(v) } }
多路复用:
func main() { ch1 := make(chan int, 10) ch2 := make(chan int, 10) ch3 := make(chan int, 10) lian9(ch1) lian10(ch2) lian11(ch3) lian8(ch1, ch2, ch3) } func lian8(ch1 chan int, ch2 chan int, ch3 chan int) { //随机输出一个 select { case data := <-ch1: fmt.Println("ch1:", data) case data := <-ch2: fmt.Println("ch2:", data) case ch3 <- 10: data := <-ch3 fmt.Println("ch3:", data) } } func lian9(ch chan int) <-chan int { ch <- 10 return ch } func lian10(ch chan int) <-chan int { ch <- 12 return ch } func lian11(ch chan int) <-chan int { ch <- 14 return ch }