开发者学堂课程【Go语言核心编程 - 面向对象、文件、单元测试、反射、TCP编程:协程并发(并行)资源竞争问题】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9751
协程并发(并行)资源竞争问题
一,channel(管道)-看个需求
把这些数的阶层放入到 map 中,最后显示出来要求使用 go green 来完成。实际上它就是用携程去做,使用这个greeting 来完成效率高,但是会出现一个并发和并行安全的问题。使用第一步,使用 growth 来完成,看看 growing并发会出现什么问题。然后去解决第一步。第二步,再运行某个程序时,如何知道是否存在资源竞争的问题。这个资源竞争怎么去做,在编译的时候,可以加个 race,这个时候我们还是新建一个文件夹。
需求:现在要计算1-200的各个数的阶乘,并且把各个数的阶乘放入到 map 中。最后显示出来。要求使用 goroutine 完成
分析思路:
使用 goroutine 来完成,效率高,但是会出现并发/并行安全问题,2) 这里就提出了不同 goroutine 如何通信的问题。
代码实现
使用 goroutine 来完成(看看使用 gorotine 并发完成会出现什么问题然后去解决)
在运行某个程序时,如何知道是否存在资源竞争问题。方法很简单,在编译该程序时,增加一个参数 race 即可。
第一步:先填需求
package main
import
(
"fmt”
)
//需求:现在要计算1-200的各个数的阶乘,并且把各个数的阶乘放入到 map 中。
//最后显示出来。要求使用 goroutine 完成
说明思路:
1.编写一个函数,来计算各个数的阶乘,并放入到 map 中.
2.我们启动的协程多个,统计的将结果放入到 map 中
3. map 应该做出一个全局的.
第二步:将得到的结果放进去var (
myMap = make(map[int]int, 10)
)
第三步:如何将数传进去
//test 函数就是计算 n!, 让将这个结果放入到 myMapfunc test() {
res : = 1
res * = 1
for
i
:
= 1; I <= n; i++ {
}
//这
里我们将 res 放入到 myMap
说明:这里容易出现保护机制
myMap[n] = res
//
concurrent map writes?
}
func main() {
说明:将 n 往 map 里放,
第四步:有多少个任务填多少个
//我们这里开启多个协程完成这个任务[200个]for
i
:
= 1; I <=
200
; i++ {
go test(i)
}
说明:相当于有200个来进行工作
//这里我们输出结果,变量这个结果for i, v := range myMap{
fmt.Printf("map[%d]=%d\n", i, v)
}
}
最后运行时可能错误
在第四步加入:
//休眠10秒钟【?】
time.sleep(time.second*10)
输出结果会出现一个经典错误
map[19
]
=0
map[74]=0
map[40]=-70609262346240000
map[90]=0
map[132]=0
map[2001
]
=0
map[153]=0
map[166]=0
map[18
]
=6402373705728000
map
[
50]=-3258495067890909184mmap[122 ]=0
map[129]=0
map[159]=0
map[77]=0
map[41]=2894979756195840000mmap[109 ]=0
map[1201
]
=0
map[133]=0
map[195]m0
map[151]m0
Found 4 data race<s>
说明:最后说发现有四个数据就是它可以准确告诉你其实在写的数据整理有四个数据产生官网,里面写出问题没有地方。已经有结果了,但是,有四个数据,产生一个竞争关系,这个就可能出现问题来解决这个竞争关系问题。