一个简单的例子:
package main import ( "fmt" "time" ) func test() { var i int for { fmt.Println(i) time.Sleep(time.Second) i++ } } func main() { go test() for { } }
例子2:
package main import ( "fmt" "sync" "time" ) //阶乘结果存储map,key-value的方式存,并定义一个锁,避免资源竞争 var ( m = make(map[int]uint64) lock sync.Mutex ) //任务编号 type task struct { n int } //计算阶乘任务 func calc(t *task) { //接受结构体的指针 var sum uint64 sum = 1 for i := 1; i < t.n; i++ { //i 从1 开始递增,因为乘以0 等于0 sum *= uint64(i) } lock.Lock() m[t.n] = uint64(sum) //要加锁,否则fatal error: concurrent map writes lock.Unlock() } func main() { //批量调用go routin for i := 0; i < 10; i++ { t := &task{n: i} //传地址 go calc(t) } time.Sleep(10 * time.Second) lock.Lock() for k, v := range m { fmt.Printf("%d! =%v\n", k, v) } lock.Unlock() }
运行结果:build时候注意添加 -race参数,查看是否存在竞争什么的。
PS F:\go> go build -race F:\go\src\go_dev\day8\example\example03\main\main.go PS F:\go> .\main.exe 0! =1 2! =1 4! =6 5! =24 7! =720 8! =5040 9! =40320 1! =1 3! =2 6! =120 PS F:\go>
channel的声明:
var 变量名 chan 类型
var test chan int
var test chan string
var test chan map[string]sting
var test chan stu
var test chan *stu //定义指针,就放地址进去下面是例子:
package main import "fmt" type student struct { Name string } func main() { /* //基本类型的channel fmt.Println("intchan") var intChan chan int intChan = make(chan int, 10) intChan <- 10 //map类型的channel fmt.Println("mapchan") var mapChan chan map[string]string mapChan = make(chan map[string]string, 10) m := make(map[string]string, 16) m["stu1"] = "001" m["stu2"] = "002" mapChan <- m //自定义的channel fmt.Println("userchan") var stuChan chan student stu := student{Name: "stu1"} stuChan <- stu v := <-stuChan fmt.Println("userchan: ", v) */ //接口类型,啥都能存 fmt.Println("intfchan") var intfChan chan interface{} intfChan = make(chan interface{}, 10) stu1 := student{Name: "stu2"} fmt.Println("intfchan<- ") intfChan <- &stu1 //读interface的chan var rintf interface{} rintf = <-intfChan //类型转换 var stu2 *student //存的是指针 stu2, ok := rintf.(*student) if !ok { fmt.Println("can not convert") return } fmt.Println(stu2) }
其中有个地方会阻塞了,还没解决,后面再来处理:
func main() { //自定义的channel fmt.Println("userchan") var stuChan chan student stu := student{Name: "stu1"} fmt.Println("userchan<- ") stuChan <- stu fmt.Println("<-userchan") v := <-stuChan fmt.Println("userchan: ", v) }
output: 在 stuChan <- stu这里卡住了
PS F:\go> .\main.exe userchan userchan<-
后面继续学习,今天点到为止~
作者:XieHZ同学