一个简单的例子:
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<-
后面继续学习,今天点到为止~