goroutine/channel(1)
channel可以是各种数据类型:
(map类型)
(struct类型)
(接口类型)
package mainimport "fmt"type student struct { name string}func main() { var stuChan chan interface{} //空interface类型可以是任意类型 stuChan = make(chan interface{}, 10) stu := student{name:"stu01"} stuChan <- &stu var stu01 interface{} stu01 = <- stuChan fmt.Println(stu01) var stu02 *student //将stu01由interface转换为结构体类型指针 stu02, ok := stu01.(*student) if !ok { fmt.Println("不可以转换") return } fmt.Println(stu02)}
输出:
&{stu01}
&{stu01}
Process finished with exit code 0
channel关闭,判断:
package mainimport "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 //从chan取数据的时候第二个参数用来判断是否成功 b, ok := <- ch if ok == false { fmt.Println("chan is closed") return } fmt.Println(b) }}
输出:
0
1
2
3
4
5
6
7
8
9
chan is closed
range遍历chan:
package mainimport "fmt"func main() { var ch chan int ch = make(chan int, 1000) for i := 0; i < 1000; i++ { ch <- i } close(ch) for v := range ch { fmt.Println(v) }}
关闭chan,goroutine同步案例:
package mainimport ( "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 } } fmt.Println("exit") //每个calc的协程(goroutine)结束后写入true到名为exitChan的chan里。代表该goroutine结束了 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++ { go calc(intChan, resultChan, exitChan) } //等待所有计算的goroutine全部退出 go func() { for i := 0; i < 8; i++ { <-exitChan fmt.Println("wait goroute ", i, " exited") } //8个goroutine结束后关闭resultChan管道 close(resultChan) }() //resultChan管道关闭后,range才能在遍历完后结束 for v := range resultChan { fmt.Println(v) }}
再来个同步channel的例子:
package mainimport ( "fmt")func send(ch chan int, exitChan chan bool) { for i := 0; i < 10; i++ { ch <- i } close(ch) exitChan <- true}func recv(ch chan int, exitChan chan bool) { for { v, ok := <- ch if !ok { break } fmt.Println(v) } exitChan <- true}func main() { ch := make(chan int, 10) exitChan := make(chan bool, 2) go send(ch, exitChan) go recv(ch, exitChan) var total = 0 for _ = range exitChan { total++ if total == 2 { break } }}
输出:
0
1
2
3
4
5
6
7
8
9
Process finished with exit code 0
channel的只读,只写(读函数里只准读,写函数里只准写。来进行规范,防止出错):
package mainimport "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 } }}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。