管道的使用介绍

现在要计算 1-N 的各个数的阶乘,并且把各个数的阶乘放入到 map 中。最后显示出来。要求使用 goroutine 完成

package main

import (
"fmt"
) var (
mymap = make(map[int]int, 10)
) func calc(n int) {
res := 1 for i := 1; i <= n; i++ {
res *= i
}
mymap[n] = res
} func main() {
for n := 1; n < 20; n++ {
go calc(n)
} for key, val := range mymap {
fmt.Printf("map[%d]=%d\n", key, val)
} }

问题1:使用goroutine时,主线程执行结束,即使协程没有执行完毕也会结束,顾map没有结果

func main() {
for n := 1; n < 20; n++ {
go calc(n)
} time.Sleep(time.Second * 3) // 加入睡眠
for key, val := range mymap {
fmt.Printf("map[%d]=%d\n", key, val)
} }

问题2:fatal error:并发写

API server listening at: 127.0.0.1:4417
fatal error: concurrent map writes
goroutine 36 [running]:
runtime.throw(0x4e0144, 0x15)
D:/programs/go/src/runtime/panic.go:608 +0x79 fp=0xc0000bff28 sp=0xc0000bfef8 pc=0x42e099
runtime.mapassign_fast64(0x4c2300, 0xc000072240, 0x12, 0x0)
D:/programs/go/src/runtime/map_fast64.go:101 +0x41a fp=0xc0000bff90 sp=0xc0000bff28 pc=0x4110ea
main.calc(0x12)
D:/go_work/src/gortoutine/1/1.go:18 +0x94 fp=0xc0000bffd8 sp=0xc0000bff90 pc=0x4aa314
runtime.goexit()
D:/programs/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000bffe0 sp=0xc0000bffd8 pc=0x456f41
created by main.main
D:/go_work/src/gortoutine/1/1.go:23 +0x70
goroutine 1 [sleep]:
time.Sleep(0xb2d05e00)
D:/programs/go/src/runtime/time.go:105 +0x132
main.main()
D:/go_work/src/gortoutine/1/1.go:26 +0x8f

排查方法:在运行某个程序时,如何知道是否存在资源竞争问题。 方法很简单,在编译该程序时,增加一个参数 -race 即可

D:\go_work>1.exe
==================
WARNING: DATA RACE
Write at 0x00c00006e240 by goroutine 7:
runtime.mapassign_fast64()
D:/programs/go/src/runtime/map_fast64.go:92 +0x0
main.calc()
D:/go_work/src/goroutine/1/1.go:18 +0x91 Previous write at 0x00c00006e240 by goroutine 6:
runtime.mapassign_fast64()
D:/programs/go/src/runtime/map_fast64.go:92 +0x0
main.calc()
D:/go_work/src/goroutine/1/1.go:18 +0x91 Goroutine 7 (running) created at:
main.main()
D:/go_work/src/goroutine/1/1.go:23 +0x6f Goroutine 6 (finished) created at:
main.main()
D:/go_work/src/goroutine/1/1.go:23 +0x6f
==================
map[5]=120
map[6]=720
map[8]=40320
map[13]=6227020800
==================
WARNING: DATA RACE
Read at 0x00c0000b6068 by main goroutine:
main.main()
D:/go_work/src/goroutine/1/1.go:27 +0x103 Previous write at 0x00c0000b6068 by goroutine 19:
main.calc()
D:/go_work/src/goroutine/1/1.go:18 +0xa6 Goroutine 19 (finished) created at:
main.main()
D:/go_work/src/goroutine/1/1.go:23 +0x6f
==================
map[14]=87178291200
map[4]=24
map[10]=3628800
map[16]=20922789888000
map[18]=6402373705728000
map[17]=355687428096000
map[19]=121645100408832000
map[1]=1
map[2]=2
map[7]=5040
map[11]=39916800
map[12]=479001600
map[15]=1307674368000
map[3]=6
map[9]=362880
Found 2 data race(s)

会提示存在两个数据竞争

低水平解决方法,给变量加锁。

package main

import (
"fmt"
"sync"
"time"
) var (
mymap = make(map[int]int, 10)
lock sync.Mutex
) func calc(n int) {
res := 1 for i := 1; i <= n; i++ {
res *= i
}
lock.Lock()
mymap[n] = res
lock.Unlock()
} func main() {
for n := 1; n < 20; n++ {
go calc(n)
} time.Sleep(time.Second * 10)
for key, val := range mymap {
lock.Lock()
fmt.Printf("map[%d]=%d\n", key, val)
lock.Unlock()
} }

这是个笨方法,大大影响程序性能

golang channle 管道的更多相关文章

  1. golang中管道热替换

    golang中管道替换问题 https://blog.csdn.net/cyk2396/article/details/78875347 1.运行以下代码: var chan1 chan int va ...

  2. golang channle阻塞

    当一个channle容量写满时,会出现阻塞状态 package main func main() { var c1 = make(chan int, 10) for i := 0; i < 10 ...

  3. golang channle close() x,ok := <- c

    close为内置函数 close内置函数关闭一个通道channle,其效果为:在最后的值从已关闭的信道中被接收后,任何对其的接收操作都会无阻塞的成功.对于已关闭的信道使用v,ok := <-   ...

  4. golang 管道

    2.管道简介Golang的原子并发特性使得它很容易构造流数据管道,这使得Golang可有效的使用I/O和多CPU特性.本文提出一些关于管道的示例,在这个过程中突出了操作失败的微妙之处和介绍处理失败的具 ...

  5. 大数据面试(HR电话了解)

    1什么是HA集群? 所谓HA,即高可用(7*24小时不中断服务) HA集群是hadoop高可用集群,即有两个namenode,一个active,一个stanby,active的name挂掉之后,sta ...

  6. golang管道

    golang中的channel channel用于goroutine之间的通信 如果不用channel,使用共享全局变量的方式,需要加锁 // synchornized 同步 // golang中的 ...

  7. Golang核心编程

    源码地址: https://github.com/mikeygithub/GoCode 第1章 1Golang 的学习方向 Go 语言,我们可以简单的写成 Golang 1.2Golang 的应用领域 ...

  8. golang:协程安全

    多路复用 Go语言中提供了一个关键字select,通过select可以监听channel上的数据流动.select的用法与switch语法类似,由select开始一个新的选择块,每个选择条件由case ...

  9. Golang, 以17个简短代码片段,切底弄懂 channel 基础

    (原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...

随机推荐

  1. 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现

    本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...

  2. SCOI2016幸运数字(树剖/倍增/点分治+线性基)

    题目链接 loj luogu 题意 求树上路径最大点权异或和 自然想到(维护树上路径)+ (维护最大异或和) 那么有三种方法可以选择 1.树剖+线性基 2.倍增+线性基 3.点分治+线性基 至于线性基 ...

  3. Python数据采集分析告诉你为何上海二手房你都买不起

    感谢关注Python爱好者社区公众号,在这里,我们会每天向您推送Python相关的文章实战干货. 来吧,一起Python. 对商业智能BI.大数据分析挖掘.机器学习,python,R等数据领域感兴趣的 ...

  4. zabbix3.4.6之监控Oracle

    新zabbix搭建配置完后,公司所有的主机是通过自动注册完成了添加,网络设备及其Templates是从旧zabbix中Export出模板,然后Import入新zabbix系统中.一些应用的监控就需要自 ...

  5. [luogu3628][bzoj1911][APIO2010]特别行动队【动态规划+斜率优化DP】

    题目描述 给你一个数列,让你将这个数列分成若干段,使其每一段的和的\(a \times sum^2 + b \times sum + c\)的总和最大. 分析 算是一道斜率优化的入门题. 首先肯定是考 ...

  6. 转----------数据库常见笔试面试题 - Hectorhua的专栏 - CSDN博客

    数据库基础(面试常见题) 一.数据库基础 1. 数据抽象:物理抽象.概念抽象.视图级抽象,内模式.模式.外模式 2. SQL语言包括数据定义.数据操纵(Data Manipulation),数据控制( ...

  7. 第一次使用cisco packet tracer

    搭建一个如图所示的网络,左边局域网是10.0.0.0网段,右边局域网是12.0.0.0网段,中间为广域网11.0.0.0网段 上面的成功了,但是不是很熟悉,下面重新来一遍 1.先用可视化界面建立一个如 ...

  8. C语言学习记录之一

    1. while语句 2. 循环嵌套 3. 数组 4. 排序 1. while 由于上节课时间有限,介绍完for循环后没有来得及讲while语句.简单来讲,while也是一种循环结构,先看一个例子: ...

  9. List双向链表容器

    list 容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线 性表,这样,对链表的任一位置的元素进行插入.删除和查找都是极快速的. 图 2-7 是 list 采用的双向循环链表的 ...

  10. python学习day6 数据类型Ⅳ(集合)

    day6 数据类型-集合 内容补充: 列表功能: .reverse()反转 v = [1,2,3,4,5,6]v.reverse()print() #[6, 5, 4, 3, 2, 1] .sort( ...