在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
go channel1、不同goroutine之间如何进行通讯?
2、channel概念
3、channel声明 var 变量名 chan 类型 var test chan int var test chan string var test chan map[string]string var test chan stu var test chan *stu 4、channel初始化 使用make进行初始化 var test chan int test = make(chan int, 10) var test chan string test = make(chan string, 10) 5、channel基本操作
var testChan chan int testChan = make(chan int, 10) var a int a = <- testChan
var testChan chan int testChan = make(chan int, 10) var a int = 10 testChan <- a channel初始化、基本操作示例: package main import "fmt" type student struct { name string } func testmap(){ var mapChan chan map[string]string mapChan = make(chan map[string]string, 10) m := make(map[string]string, 16) m["stu01"] = "123" m["stu02"] = "456" mapChan <- m } func teststruct(){ var structChan chan student structChan = make(chan student, 10) stu := student { name: "stu01", } structChan <- stu } func teststruct1(){ var structChan chan *student structChan = make(chan *student, 10) stu := student { name: "stu01", } structChan <- &stu } func main() { var stuChan chan interface{} stuChan = make(chan interface{}, 10) stu := student{name: "stu01"} stuChan <- &stu var stu01 interface{} stu01 = <-stuChan var stu02 *student stu02, ok := stu01.(*student) if !ok { fmt.Println("can not convert") return } fmt.Println(stu02) } goroutine和channel相结合示例 package main import ( "fmt" "time" ) func write(ch chan int) { for i := 0; i < 100; i++ { ch <- i fmt.Println("put data:", i) } } func read(ch chan int) { for { var b int b = <-ch fmt.Println("get data:", b) time.Sleep(time.Second) } } func main() { intChan := make(chan int, 10) go write(intChan) go read(intChan) time.Sleep(100 * time.Second) } 6、channel特点
如下所示,testChan只能放一个元素: var testChan chan int testChan = make(chan int) var a int a = <- testChan 如下所示,testChan是带缓冲区的chan,一次可以放10个元素: var testChan chan int testChan = make(chan int, 10) var a int = 10 testChan <- a 7、chan的关闭 使用内置函数close进行关闭,chan关闭之后,for range遍历chan中 已经存在的元素后结束 使用内置函数close进行关闭,chan关闭之后,没有使用for range的写法 需要使用,v, ok := <- ch进行判断chan是否关闭 package main import "fmt" func main() { var ch chan int ch = make(chan int, 10) for i := 0; i < 10; i++ { ch <- i } close(ch) for { var b int b, ok := <-ch if ok == false { fmt.Println("chan is close") break } fmt.Println(b) } } 8、channel range package main import "fmt" func main() { var ch chan int ch = make(chan int, 1000) for i := 0; i < 10; i++ { ch <- i } close(ch) for v := range ch { fmt.Println(v) } } 使用channel关闭,再使用channel range轮询完channel中的值后自动结束。 9、channel之间同步 package main import "fmt" func send(ch chan int, exitChan chan struct{}) { for i := 0; i < 10; i++ { ch <- i } close(ch) var a struct{} exitChan <- a } func recv(ch chan int, exitChan chan struct{}) { for { v, ok := <-ch if !ok { break } fmt.Println(v) } var a struct{} exitChan <- a } func main() { var ch chan int ch = make(chan int, 10) exitChan := make(chan struct{}, 2) go send(ch, exitChan) go recv(ch, exitChan) var total = 0 for _ = range exitChan { total++ if total == 2 { break } } }
结合上述channel所有功能以及结合goroutine代码示例 package main import ( "fmt" ) func calc(taskChan chan int, resChan chan int, exitChan chan bool) { // 素数判断 for v := range taskChan { flag := true for i := 2; i < v; i++ { if v%i == 0 { flag = false break } } if flag { resChan <- v // 满足条件的素数放入resChan } } fmt.Println("exit") exitChan <- true } func main() { intChan := make(chan int, 1000) resultChan := make(chan int, 1000) exitChan := make(chan bool, 8) go func() { for i := 0; i < 10000; i++ { intChan <- i } close(intChan) }() for i := 0; i < 8; i++ { // 启动8个goroutine go calc(intChan, resultChan, exitChan) } // 等待所有计算的goroutine全部退出 go func() { for i := 0; i < 8; i++ { <-exitChan fmt.Println("wait goroute ", i, " exited") } close(resultChan) }() for v := range resultChan { fmt.Println(v) } }
10、chan的只读和只写
Var 变量的名字 <-chan int Var readChan <- chan int
Var 变量的名字 chan<- int Var writeChan chan<- int 示例: package main import "fmt" func send(ch chan<- int, exitChan chan struct{}) { for i := 0; i < 10; i++ { ch <- i } close(ch) var a struct{} exitChan <- a } func recv(ch <-chan int, exitChan chan struct{}) { for { v, ok := <-ch if !ok { break } fmt.Println(v) } var a struct{} exitChan <- a } func main() { var ch chan int ch = make(chan int, 10) exitChan := make(chan struct{}, 2) go send(ch, exitChan) go recv(ch, exitChan) var total = 0 for _ = range exitChan { total++ if total == 2 { break } } }
11、chan进行select操作 样例一: package main import "fmt" import "time" func main() { var ch chan int ch = make(chan int, 10) ch2 := make(chan int, 10) go func() { var i int for { ch <- i time.Sleep(time.Second) ch2 <- i * i time.Sleep(time.Second) i++ } }() for { select { case v := <-ch: fmt.Println(v) case v := <-ch2: fmt.Println(v) default: fmt.Println("get data timeout") time.Sleep(time.Second) } } } 样例二: package main import ( "fmt" "time" ) func main() { var ch chan int ch = make(chan int, 1) go func() { var i int for { select { case ch <- i: default: fmt.Println("channel is full") time.Sleep(time.Second) } i++ } }() for { v := <-ch fmt.Println(v) } }
|
请发表评论