package main
import (
"fmt"
sync"
)
var (
myMap = make(map[int]int,10)
)
func cal(n int) {
res := 1
for i := 1; i <= n; i++ {
res *= i
}
myMap[n] = res
}
func main() {
1; i <= 15; i++ {
go cal(i)
}
for i,v := range myMap {
fmt.Printf(map[%d]=%dn,i,v)
}
}
"
""
)
//lock是全局互斥锁,synchornized
lock sync.Mutex
)
func cal(n i
}
lock.Lock()
myMap[n] = res
.Unlock()
}
func main() {
{
go cal(i)
}
range myMap {
fmt.Printf(
?
?
有可能主程序运行完了而cal还没运行完(上面结果只到13,没有14,15),需要加上time.Sleep(time.Seconde*3),而在输出时,由于主协程并不知道程序已经完成了,底层仍然可能出现竞争资源,所以在输出阶段也要加上互斥锁。最终代码如下:
lock sync.Mutex
)
func cal(n i
}
.Lock()
myMap[n] = res
.Unlock()
}
func main() {
{
go cal(i)
}
time.Sleep(time.Second * 4)
lock.Lock()
.Unlock()
}
为什么需要管道?
(1)主线程在等待所有协程全部完成的时间很难确定;
(2)如果主线程休眠时间长了,会加长等待时间,如果等待时间短了,可能协程还处于工作状态,这时也会随着主协程的结束而销毁;
(3)通过全局变量加锁同步来实现通讯,也并不利于多个协程对全局变量的读写操作;
管道的介绍:
(1)管道的本质就是一种数据结构--队列;
(2)数据先进先出;
(3)线程安全,多协程访问时,不需要加锁;
(4)管道只能存储相同的数据类型;
管道的声明:
var intChan chan int;
var stringChan chan string;
var mapChan chan map[int]string;
var perChan chan Person;
var perChan chan *Person;
注意:管道是引用类型;管道必须初始化后才能写入数据;管道是有类型的,即IntChan只能写入int;
管道初始化:
var intChan chan int
intChan = make(chan int,10)
向管道中读写数据:
num := 10
intChan<-num
var num2 int
num2<-intChan
注意:管道容量满了则不能继续写入,在没有使用协程的情况下,管道空了不能继续读取。
如何使管道中存储任意数据类型?

(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!