package main; import ( "fmt" "runtime" "sync" ) //goruntine奉行通过通信来共享内存,而不是共享内存来通信 //channel是goruntine沟通的桥梁,大都是阻塞同步的 //通过make创建,close关闭 //channel是引用类型 //使用for range来迭代操作channel //可设置单向或双向通道 //可设置缓存大小,在未被填满前不会发生阻塞 func main() { //这里需要设置chan的类型 ch := make(chan bool); go func() { fmt.Println("run..."); ch <- true; }(); //这里是阻塞的,等到匿名函数执行完成,给ch设置为true时 //这里能读取出数据时,就退出。 <-ch; ch1 := make(chan bool); go func() { fmt.Println("run..."); ch1 <- true; close(ch1); }(); //对chan进行迭代操作时,必须在某个地方关闭该chan,不然会发生死锁 for v := range ch1 { fmt.Println(v); } //有缓存是异步的 ch2 := make(chan bool, 1); go func() { fmt.Println("run..."); <-ch2; }(); ch2 <- true; //使用多核 runtime.GOMAXPROCS(runtime.NumCPU()); ch3 := make(chan bool, 10); for i := 0; i < 10; i++ { go run(ch3, i); } //这里读取10次,跟上面go run()执行次数相同 //保证10次运行都执行完,才退出 for i:= 0; i < 10; i++ { <-ch3; } //这里创建任务 wg := sync.WaitGroup{}; wg.Add(10); for i := 0; i < 10; i++ { go run2(&wg, i); } //等待所有任务完成 wg.Wait(); //有多个chan时,如何处理 ch4, ch5 := make(chan int), make(chan string); //用于判断是否关闭 ch6 := make(chan bool); go func() { for { select { case v, ok := <-ch4: if !ok { ch6 <- true; break; } fmt.Println(v); case v, ok := <-ch5: if !ok { ch6 <- true; break; } fmt.Println(v); } } }(); ch4 <- 1; ch4 <- 2; ch5 <- "hello"; ch5 <- "world"; close(ch4); close(ch5); //循环读取二次 for i := 0; i < 2; i++ { <-ch6; } } func run(ch chan bool, ix int) { a := 0; for i := 1; i < 10000; i++ { a += i; } fmt.Println(ix, a); //给chan传递true,说明该run执行结束 ch <- true; } func run2(wg *sync.WaitGroup, ix int) { a := 0; for i := 1; i < 10000; i++ { a += i; } fmt.Println(ix, a); //任务完成 wg.Done(); }